我需要按特定值对字典列表进行排序。不幸的是,有些值是None,并且排序在Python 3中不起作用,因为它不支持None与None值的比较。我还需要保留None值,并将它们作为最低值放在新的排序列表中。
代码:
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 3中重新创建Python 2的排序行为。但我没有看到与运营商合作的方法。
答案 0 :(得分:4)
我通过在值上使用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
可能还有另一种方法来编写&#34;加权&#34;功能较短但有效。这个想法只是返回-infinite为None值,然后按值排序。
我希望它有所帮助,
答案 1 :(得分:3)
对于Python 3:如here所述,您可以根据自己的情况执行以下操作:
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}
]
L.sort(key= lambda x: (x['value'] is not None, x['value']), reverse=True)
print(L)
>>>[{'value': 4, 'other_value': 1}, {'value': 3, 'other_value': 9001}, {'value': 2, 'other_value': 3}, {'value': 1, 'other_value': 4}, {'value': None, 'other_value': 2}, {'value': None, 'other_value': 42}]
答案 2 :(得分:1)
我将首先过滤掉None
个值,然后按照通常的方式进行排序:
my_list = [d for d in my_list if all(d.values())]
答案 3 :(得分:1)
maxsize
是 Python 数据结构的最大大小,例如列表中可以包含多少个元素。
从技术上讲,这不是最小的可能整数(因为 Python 3 具有无界整数值),但在正常用例中应该足够了。
import operator
import sys
my_list = [
{"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}
]
def key(e):
v = e["value"]
return -sys.maxsize if v is None else v
new_sorted_list = sorted((my_list ),
key=key, reverse=True
)
print(new_sorted_list)
给予,
[{'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': 9001}]
[Program finished]