1

出于某种原因,考虑到我在 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,所以我已经对其进行了更改以处理它。

4

2 回答 2

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)
于 2013-03-04T03:20:51.420 回答
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)

虽然这有创建大量(可能未使用的)列表的缺点,但在将默认设置为列表的特殊情况下,通常最好使用 a defaultdict,然后将其复制到常规 dict 以去除默认值价值。这并不特别适用于不可变类型,例如intor str

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

于 2013-03-04T03:48:58.500 回答