2017-08-17 89 views
0

我需要按特定值对字典列表进行排序。不幸的是,有些值为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排序行为当没有涉及字典。但我不认为有办法与运营商合作。

回答

2

我找到了一种通过在值上使用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值,然后按值排序。

我希望它能帮助,

+2

'回报-float( 'INF')如果NB再无别nb'会表达更短的方式'加权()'。 :-) – BlackJack