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

NSP*_*NSP 3 python sorting generator

我的代码有以下几行

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]
Run Code Online (Sandbox Code Playgroud)

输出:

type is <type 'generator'>
Run Code Online (Sandbox Code Playgroud)

列表中的对象是:

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>
Run Code Online (Sandbox Code Playgroud)

每个警报由以下数据组成

 {'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}
Run Code Online (Sandbox Code Playgroud)

我如何迭代生成器?

alarm_list = sorted(get_alarm_list,
                    key=lambda a: a.severity,
                    reverse=True)
Run Code Online (Sandbox Code Playgroud)

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

And*_*yko 5

您的代码中的问题是您正在尝试对耗尽的生成器进行排序(您在for循环思想生成器之后进行排序)。您可以对生成器对象产生的结果进行排序,因此您的选择是将生成器耗尽到变量中,换句话说,基于get_alarm_listas创建新列表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
Run Code Online (Sandbox Code Playgroud)

注 1:执行list(get_alarm_list)- get_alarm_list生成器后变为空。唯一存储结果的项目conn.query_alarmssorted_get_alarm_list. 您可以在Generators Python Wiki上阅读有关生成器的更多信息了解 Python 中的生成器

注 2:实际上,您可以将生成器对象传递给sorted并且您将获得与传递相同的列表list(generator),但是sorted如果您将列表传递给它,效果会更快(请参阅使用 Generator Expressions 而不是 Lists 的SO answer sorted() 的更多信息)。

  • 你的笔记得到了正确的答案,但我认为你真的应该改变你的第一句话。说你不能对生成器进行排序是完全错误的。 (2认同)