如何在对排序列表进行排序时使用operator.itemgetter忽略无值?
问题描述:
我需要按特定值对字典列表进行排序。不幸的是,有些值为None,排序在Python 3中不起作用,因为它不支持比较None和非None值。我还需要保留None值,并将它们作为最低值放入新的排序列表中。如何在对排序列表进行排序时使用operator.itemgetter忽略无值?
代码:
import operator
list_of_dicts_with_nones = [
{"value": 1, "other_value": 4},
{"value": 2, "other_value": 3},
{"value": 3, "other_value": 2},
{"value": 4, "other_value": 1},
{"value": None, "other_value": 42},
{"value": None, "other_value": 9001}
]
# sort by first value but put the None values at the end
new_sorted_list = sorted(
(some_dict for some_dict in list_of_dicts_with_nones),
key=operator.itemgetter("value"), reverse=True
)
print(new_sorted_list)
我得到在Python 3.6.1什么:
Traceback (most recent call last):
File "/home/bilan/PycharmProjects/py3_tests/py_3_sorting.py", line 15, in <module>
key=operator.itemgetter("value"), reverse=True
TypeError: '<' not supported between instances of 'NoneType' and 'NoneType'
我需要什么(这个作品在Python 2.7):
[{'value': 4, 'other_value': 1}, {'value': 3, 'other_value': 2}, {'value': 2, 'other_value': 3}, {'value': 1, 'other_value': 4}, {'value': None, 'other_value': 42}, {'value': None, 'other_value': 10001}]
是,我知道这个问题有类似的问题,但是他们没有用operator.itemgetter处理这个特殊的用例:
A number smaller than negative infinity in python?
Is everything greater than None?
Comparing None with built-in types using arithmetic operators?
我可以重新创建的Python 2的在Python 3排序行为当没有涉及字典。但我不认为有办法与运营商合作。
答
我找到了一种通过在值上使用lambda键来实现它的方法。这是代码:
L = [ # I mixed them to shown the sorting
{"value": 1, "other_value": 4},
{"value": 2, "other_value": 3},
{"value": None, "other_value": 2},
{"value": 4, "other_value": 1},
{"value": None, "other_value": 42},
{"value": 3, "other_value": 9001}
]
def weighted(nb):
if nb is None:
return -float('inf')
else:
return nb
L.sort(key=lambda x:weighted(x["value"]), reverse=True)
print(L) # => return the expected output in python 3.6
有可能是另一种方式来写的“加权”功能短,但它的工作原理。这个想法只是返回-infinite for None值,然后按值排序。
我希望它能帮助,
'回报-float( 'INF')如果NB再无别nb'会表达更短的方式'加权()'。 :-) – BlackJack