[英]How to sort generator type in python
My code has below lines 我的代码有以下几行
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]
Output: 输出:
type is <type 'generator'>
The objects in the list are: 列表中的对象是:
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>
And each alarm consists of the below data 并且每个警报包含以下数据
{'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}
How can i iterate over the generator? 我如何迭代生成器?
alarm_list = sorted(get_alarm_list,
key=lambda a: a.severity,
reverse=True)
But here alarm_list
is empty. 但是这里
alarm_list
为空。 How can i use sort function on generator get_alarm_list
如何在生成器
get_alarm_list
上使用排序功能
The problem in your code is that you are trying to sort exhausted generator ( you sorting after for
loop thought generator). 在你的代码的问题是,你正在试图理清疲惫发生器(您整理后
for
循环发电机思想)。 You can sort result produced by generator object, so the option for you is to exhaust generator into variable in other words to create new list based on get_alarm_list
as list(generator)
and then iterate and sort it with simple sorted function or list.sort
method: 您可以对生成器对象产生的结果进行排序,因此您的选择是将生成器耗尽为变量,换句话说,基于
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
Note 1 : After execution of list(get_alarm_list)
- get_alarm_list
generator became empty. 注意1 :执行
list(get_alarm_list)
get_alarm_list
生成器为空。 And the only item which store result of conn.query_alarms
is the sorted_get_alarm_list
. 并且存储
conn.query_alarms
结果的唯一项目是sorted_get_alarm_list
。 You can read more about generators on Generators Python Wiki and Understanding Generators in Python 您可以在Generators Python Wiki上 了解有关Generators的更多信息,并在Python中了解Generators
Note 2 : Actually you can pass generator object to sorted
and you will get same list as passing list(generator)
, however sorted
works faster if you pass a list to it ( see more on SO answer sorted() using Generator Expressions Rather Than Lists ). 注2 :实际上,您可以传递生成器对象进行
sorted
并且将得到与传递list(generator)
相同的列表,但是如果将列表传递给它,则sorted
工作得更快(有关更多信息,请参见使用生成器表达式而不是列表的生成器表达式sorted()) )。
The problem you're running into is that you're consuming the whole generator in your for
loop when you modify the severity
attributes of your objects. 您遇到的问题是,修改对象的
severity
属性时,您在for
循环中消耗了整个生成器。 That means there's nothing left to iterate on when you call sorted
, since generators are good for one use only. 这意味着在调用
sorted
,无需进行任何迭代,因为生成器仅适合一种用途。
You can fix this by getting rid of the first loop, and putting the severity-transforming logic into the key
lambda function: 您可以通过摆脱第一个循环并将严重性转换逻辑放入
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))
Note that I've renamed your get_alarms_list
variable to be less misleading (it's not a list). 请注意,我已将您的
get_alarms_list
变量重命名为具有较小的误导性(这不是列表)。 I've also made it so that reverse=True
is not needed in the sorted call by mapping the higher priorities to negative key values. 我也做到了,通过将较高优先级映射到负键值,在排序调用中不需要
reverse=True
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.