2016-06-10 92 views
1
发电机类型

我的代码有以下行如何排序在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

+0

'sorted'在发电机上工作。它会返回一个排序列表。你能发布足够的代码来重现你的问题吗? – khelwood

+0

@khelwood我编辑了我的问题,并发布了更多代码作为您的建议。 – NSP

+0

在版本2中,您可以使用'for index,枚举值(get_alarm_list)'并将'get_alarm_list'更新为'get_alarm_list [index]',因此您不需要创建分列表... –

回答

3

您的代码中的问题是,您正在尝试排序耗尽的发生器(在for循环思想发生器之后排序)。您可以按发电机对象生成的结果,这样对你的选择是排发电机进换句话说可变基于get_alarm_listlist(generator)创造新的名单,然后进行迭代,并用简单的sorted功能或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。你可以阅读更多关于发电机上​​和Understanding Generators in Python

注2:其实你可以通过发电机对象sorted,你会得到相同的列表,通过list(generator),但是sorted工作更快,如果你传递一个列表(见更多关于SO的回答sorted() using Generator Expressions Rather Than Lists)。

+0

基本上我在代码中试过的东西就像''在get_alarm_list中报警:如果alarm.severity == 2,alarm_list.append(alarm)'。这里我修改了ob对象后附加了一个名为'alarm_list'的列表。这是对的吗? – NSP

+0

我尝试了'list(get_alarm_list)'按照你的建议。但它是空的。 '打印清单(get_alarm_list)'。输出是'[]' – NSP

+0

是的,因为在第一次执行列表(get_alarm_list)后发生器是空的。 –

0

您遇到的问题是当您修改对象的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是不需要在排序的调用通过映射更高的优先级为负值键值。

+0

非常简洁,完美的作品。通过这种方式,对象的严重性值将保留并不会转换为整数。 +1 – 2016-06-12 01:22:40