更优雅/ pythonic的方式附加到数组或创建它

时间:2013-03-04 03:14:55

标签: python arrays

出于某种原因,下面的代码对我来说有点麻烦,考虑到我在Python中发现的所有语法糖,所以我想询问是否有更好的方法:

pictures = list_of_random_pictures()
invalid_pictures = {}
for picture in pictures:
    if picture_invalid(picture):
        if not invalid_pictures.get(picture.album.id):
            invalid_pictures[picture.album.id] = []
        invalid_pictures[picture.album.id].append(picture)

所以只是为了澄清,我想知道是否有更可读的方式来处理上面的最后3行。当我重复invalid_pictures[picture.album.id] 3次时,如果它完全可以避免,那似乎是不必要的。

编辑:刚刚意识到我上面的代码会出现KeyError,所以我对其进行了修改以处理它。

2 个答案:

答案 0 :(得分:4)

事实上,标准库中有一个对象可以完全处理这种情况:collections.defaultdict

它的参数是一个类型或函数,它产生缺失键的默认值。

from collections import defaultdict

invalid_pictures = defaultdict(list)
for picture in pictures:
    if picture_invalid(picture):
        invalid_pictures[picture.album.id].append(picture)

答案 1 :(得分:2)

虽然我确实发现Joel的答案是通常的解决方案,但有一个经常被忽视的功能,有时候是可取的。如果不特别需要默认值,则使用dict.setdefault(),当插入默认值时会出现异常(并且collections.defaultdict不是最理想的。适合使用setdefault()的代码将是

pictures = list_of_random_pictures()
invalid_pictures = {}
for picture in pictures:
    if picture_invalid(picture):
        invalid_pictures.setdefault(picture.album.id, []).append(picture)

虽然这有创建很多(可能是未使用的)列表的缺点,所以在将默认设置为列表的特定情况下,使用defaultdict通常更好,然后将其复制到一个普通的字典来剥离默认值。这并不特别适用于不可变类型,例如intstr

例如,pep-333要求environ变量是常规dict,而不是collections.Mapping的子类或实例,而是真正的,简单的'dict'。另一种情况是,你不是通过迭代器并应用于平面映射;但每个密钥都需要特殊处理,例如将默认值应用于配置时。