在Python 3.7中,一步完成字典中列表的初始化并添加值。

5

我有一个字典,其中键是字符串而值是列表。

现在,在添加与给定键关联的值时,我总是需要检查是否已经有了列表,否则我必须将其初始化为空列表,类似于以下代码段:

      if not k in myDict:
          myDict[k] = []
      myDict[k].append(v)

我想知道在Python 3.7中是否有将这些步骤合并为单个步骤的方法。


2
你可以考虑使用defaultdict - Łukasz Rogalski
2个回答

7
至少有三种方法:
使用 `dict.setdefault` 方法。
>>> data = {}
>>> data.setdefault('foo', []).append(42)
>>> data
{'foo': [42]}

使用 defaultdict,它与 .setdefault 不同,可以接受一个可调用对象作为参数:
>>> from collections import defaultdict
>>> data = defaultdict(list)
>>> data
defaultdict(<class 'list'>, {})
>>> data['foo'].append(42)
>>> data
defaultdict(<class 'list'>, {'foo': [42]})

最后,子类化 dict 并实现 __missing__

>>> class MyDict(dict):
...     def __missing__(self, key):
...         self[key] = value  = []
...         return value
...
>>> data = MyDict()
>>> data['foo'].append(42)
>>> data
{'foo': [42]}

请注意,您可以将最后一个视为最灵活的选项,处理它时可以访问实际丢失的键。 defaultdict 是一个类工厂,它还生成一个 dict 的子类。但是,可调用对象不接受任何参数,尽管如此,它对于大多数需求已足够。
此外,请注意,defaultdict__missing__ 方法会保留默认行为,这可能在创建数据结构后是不希望的,通常情况下您可能会想要抛出 KeyError,或者至少您不希望 mydict[key] 再添加一个键。
在两种情况下,您都可以从字典子类创建普通字典,例如 dict(data)。这通常应该非常快,即使是对于大型 dict 对象,特别是如果这是一次性成本。对于 defaultdict,您也可以将 default_factory 设置为 None,然后旧行为就会返回:
>>> data = defaultdict(list)
>>> data
defaultdict(<class 'list'>, {})
>>> data['foo']
[]
>>> data['bar']
[]
>>> data
defaultdict(<class 'list'>, {'foo': [], 'bar': []})
>>> data.default_factory = None
>>> data['baz']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'baz'
>>>

6
您可以使用 dict.setdefault
>>> d = {}
>>> d.setdefault('k', []).append(1)
>>> d
{'k': [1]}
>>> d.setdefault('k', []).append(2)
>>> d
{'k': [1, 2]}

关于字典 method_descriptor 的帮助:

dict.setdefault = setdefault(...) D.setdefault(k[,d]) -> 如果 k 不在 D 中,则返回 D[k]=d,否则返回 D.get(k,d)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接