如何在python中对生成器类型进行排序
我的代码有以下几行如何在python中对生成器类型进行排序,python,sorting,generator,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
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'>
如何迭代生成器
alarm_list = sorted(get_alarm_list,
key=lambda a: a.severity,
reverse=True)
但是这里的报警列表是空的。如何在生成器上使用排序功能
get\u alarm\u list
代码中的问题是您正在尝试对耗尽的生成器进行排序(您在之后对循环思维生成器进行排序)。您可以对generator对象生成的结果进行排序,因此您可以选择将generator耗尽到变量中,换句话说,根据get\u alarm\u list
作为list(generator)
创建新列表,然后使用简单函数或list对其进行迭代和排序。排序方法:
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:执行列表(获取报警列表)
-获取报警列表后,生成器变为空。存储conn.query\u报警结果的唯一项目是sorted\u get\u alarm\u列表
。您可以在和上阅读有关发电机的更多信息
注2:实际上,您可以将生成器对象传递给已排序的
,您将得到与传递列表(生成器)
相同的列表,但是如果您将列表传递给它,则已排序的
工作得更快(请参阅更多关于此答案的信息).您遇到的问题是,当您修改对象的严重性属性时,您在for
循环中消耗了整个生成器。这意味着当您调用排序后的时,没有什么可以重复的了,因为生成器只适合一次使用
您可以通过去掉第一个循环,并将严重性转换逻辑放入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\u alarms\u list
变量,以减少误导(它不是一个列表)。通过将较高优先级映射到负键值,我还使排序调用中不需要reverse=True
。基本上,我在代码中尝试的是类似于get\u alarm\u list中报警的:如果alarm.severity==2,则alarm\u list.append(报警)
。在修改对象的内容后,我在这里添加了一个列表报警列表
。是否正确?我按照您的建议尝试了list(获取报警列表)
。但它是空的<代码>打印列表(获取报警列表)
。输出为[]
是,因为在第一次执行列表(获取报警列表)后,生成器为空。感谢您的详细解释。我使用了一个列表,在修改严重性后将报警对象附加到该列表中。然后我将这个列表传递给排序方法。你认为这样做可以吗?你的笔记得到了正确的答案,但我认为你真的应该改变你的第一句话。说你不能对生成器进行排序是完全错误的。sorted
对生成器有效。它将返回一个排序列表。你能发布足够的代码来重现你的问题吗?@khelwood我已经编辑了我的问题,并根据你的建议发布了更多的代码。在第2版中,你可以使用作为索引,枚举(获取报警列表)中的值,并将获取报警列表更新为获取报警列表[index]
,因此,您不需要创建分离列表……问题是,您首先迭代get\u alarm\u list
,从而使用该生成器,下面对sorted(get\u alarm\u list)
的调用将导致空列表,因为get\u alarm\u list
没有更多元素。非常简洁,工作非常完美。这样可以保留对象的严重性值,而不会将其转换为整数+1与使用容易遗漏和混淆的-2
和-1
相比,为什么不使用reverse=True
?@NicHartley:这可能有效。您还可以使用按需要排序的任何其他值,因此可以执行{'critical':0,'mediate':1}.get(x.severity,2)
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
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))