Python按属性排序,可以是None

时间:2016-09-19 11:09:02

标签: python python-2.7 sorting

假设我有一个我要排序的项目列表:items = [ item1, item2, item3 ]。我想用它来对它们进行排序的属性是item.data.value,所以我通常会去:

sorted(items, key=attrgetter('data.value'))

那就行得很好。但是,data实际上可能是None,所以显然我无法访问value

你通常如何处理这样的情景?

PS:this questionthis one都没有帮助。

6 个答案:

答案 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