繁体   English   中英

如何在python中对生成器类型进行排序

[英]How to sort generator type in python

我的代码有以下几行

get_alarm_list = conn.query_alarms(query.filter_expr,
                                   query.orderb) 
print "type is:", type(get_alarm_list)
for alarm in get_alarm_list:
    if alarm.severity == 'critical':
        alarm.severity = 2
    elif alarm.severity == 'moderate':
        alarm.severity = 1
    else:
        alarm.severity = 0

alarm_list = sorted(get_alarm_list),
                    key=lambda a: a.severity,
                    reverse=True)
return [alarms.Alarm.from_db_model(alarm)
        for alarm in alarm_list]

输出:

type is <type 'generator'>

列表中的对象是:

for alarm in get_alarm_list:
     print alarm

Output:
<aodh.storage.models.Alarm object at 0x7fa4c0cb1c50>
<aodh.storage.models.Alarm object at 0x7fa4c0cb17d0>
<aodh.storage.models.Alarm object at 0x7fa4c0d86f10>
<aodh.storage.models.Alarm object at 0x7fa4ca372110>
<aodh.storage.models.Alarm object at 0x7fa4ca372190>
<aodh.storage.models.Alarm object at 0x7fa4c0c55d90>

并且每个警报包含以下数据

 {'alarm_actions': [u'log://'], 'ok_actions': [], 'description': u'instance running hot', 'state': u'insufficient data', 'fields': ['alarm_actions', 'ok_actions', 'severity', 'timestamp', 'description', 'time_constraints', 'enabled', 'state_timestamp', 'rule', 'alarm_id', 'state', 'insufficient_data_actions', 'repeat_actions', 'user_id', 'project_id', 'type', 'name'], 'repeat_actions': False, 'enabled': True, 'state_timestamp': datetime.datetime(2016, 5, 27, 6, 41, 5, 987428), 'rule': {u'meter_name': u'cpu_util', u'evaluation_periods': 3, u'period': 600, u'statistic': u'avg', u'threshold': 70.0, u'query': [], u'comparison_operator': u'gt', u'exclude_outliers': False}, 'name': u'ddd', 'alarm_id': u'f5045ed5-5c53-4a6e-be53-23d3368f40c6', 'time_constraints': [], 'insufficient_data_actions': [], 'timestamp': datetime.datetime(2016, 5, 27, 6, 41, 5, 987428), 'user_id': u'9a65b258b5a24e74ac5feae2f6c54229', 'project_id': u'28d1c27e782c4448bf53da00f49d3e1b', 'type': u'threshold', 'severity': 2}

我如何迭代生成器?

alarm_list = sorted(get_alarm_list,
                    key=lambda a: a.severity,
                    reverse=True)

但是这里alarm_list为空。 如何在生成器get_alarm_list上使用排序功能

在你的代码的问题是,你正在试图理清疲惫发生器(您整理后for循环发电机思想)。 您可以对生成器对象产生的结果进行排序,因此您的选择是将生成器耗尽为变量,换句话说,基于get_alarm_list作为list(generator)创建新列表,然后使用简单的排序函数或list.sort方法对其进行迭代和排序:

get_alarm_list = conn.query_alarms(query.filter_expr, query.orderb) 
sorted_alarm_list = sorted(list(get_alarm_list),
                               key=lambda a: a.severity,
                               reverse=True)
for alarm in sorted_alarm_list:
    print alarm

注意1 :执行list(get_alarm_list) get_alarm_list生成器为空。 并且存储conn.query_alarms结果的唯一项目是sorted_get_alarm_list 您可以在Generators Python Wiki上 了解有关Generators的更多信息,在Python中了解Generators

注2 :实际上,您可以传递生成器对象进行sorted并且将得到与传递list(generator)相同的列表,但是如果将列表传递给它,则sorted工作得更快(有关更多信息,请参见使用生成器表达式而不是列表的生成器表达式sorted()) )。

您遇到的问题是,修改对象的severity属性时,您在for循环中消耗了整个生成器。 这意味着在调用sorted ,无需进行任何迭代,因为生成器仅适合一种用途。

您可以通过摆脱第一个循环并将严重性转换逻辑放入key lambda函数中来解决此问题:

alarms_gen = conn.query_alarms(query.filter_expr, query.orderb) 
alarms_list = sorted(alarms_gen,
                     key=lambda x: {'critical': -2, 'moderate': -1}.get(x.severity, 0))

请注意,我已将您的get_alarms_list变量重命名为具有较小的误导性(这不是列表)。 我也做到了,通过将较高优先级映射到负键值,在排序调用中不需要reverse=True

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM