假设我有一个我要排序的项目列表:items = [ item1, item2, item3 ]
。我想用它来对它们进行排序的属性是item.data.value
,所以我通常会去:
sorted(items, key=attrgetter('data.value'))
那就行得很好。但是,data
实际上可能是None
,所以显然我无法访问value
。
你通常如何处理这样的情景?
PS:this question和this one都没有帮助。
答案 0 :(得分:3)
sorted(items, key=lambda i: i.data.value if i.data else 0)
答案 1 :(得分:3)
用作元组的关键字,例如(False, value)
。如果value为None,则元组应为(True, None)
。
首先比较元组的第一个元素,然后是第二个元素,等等。在True之前进行错误排序。因此,所有None值都将排序到最后。
def none_to_end_key(item):
value = item.data.value if item.data else None
return (value is None, value)
sorted(items, key=none_to_end_key)
将所有None值排序到最后。
我现在看到你已经标记了你的问题Python-2.7,那么这可能是矫枉过正的。在Python 3中,将None与整数或字符串进行比较会引发异常,因此您不能简单地使用None和其他值对列表进行排序,这样就需要这样的事情。
答案 2 :(得分:1)
只需在排序前过滤“无”
sorted(filter(None, items), key=attrgetter('data.value'))
答案 3 :(得分:0)
如果你没有方便的函数返回你想要的密钥,那么就自己编写。
def item_key(item):
try:
return item.data.value
except AttributeError:
return None
sorted(items, key=item_key)
答案 4 :(得分:0)
只需先过滤None值,然后再将它们发送到已排序。
sorted(filter(None, items), key=attrgetter('data.value'))
如果你真的想要无物品,你也可以这样做:
# items already defined with values
new_items_list = sorted(filter(None, items), key=attrgetter('data.value'))
new_items_list.extend([None] * (len(items) - len(new_items_list)))
但是,我不确定你是否真的需要无物品。
编辑:修正了将保留无项目的结束代码。
答案 5 :(得分:-1)
具有默认值支持的attrgetter。
的行为类似于dictionary.get()
D.get(k[,d]) -> D[k] if k in D, else d
d默认为None。详细信息: groups.google.com:python-ideas