Python 如何使用 defaultdict fromkeys 生成带有预定义键和空列表的字典

Che*_*eng 8 python

这是代码:

from collections import defaultdict

result = defaultdict.fromkeys(['a','b','c'], list)
result['a'].append(1)

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-44-6c01c8d56a42> in <module>()
----> 1 result['a'].append('1')

TypeError: descriptor 'append' requires a 'list' object but received a 'str'
Run Code Online (Sandbox Code Playgroud)

我不明白错误信息,出了什么问题以及如何解决?

daw*_*awg 6

该.fromkeys 方法主要用于将 dict 设置为单个相同的默认值:

>>> {}.fromkeys(['a','b','c'])
{'a': None, 'c': None, 'b': None}
Run Code Online (Sandbox Code Playgroud)

它不会为每个键(这是什么list或[]现在是什么)调用一个函数。

默认字典需要一个“工厂函数”作为默认字典:

>>> from collections import defaultdict
>>> result=defaultdict(list)
>>> result
defaultdict(<type 'list'>, {})
Run Code Online (Sandbox Code Playgroud)

list每当将缺少的键添加到 defaultdict 以形成默认值时,都会调用工厂函数(在本例中为)。

因此,要使用键设置三个列表,'a','b','c'您将执行以下操作:

>>> for e in ('a','b','c'):
...    result[e]       # 'e' is not in the dict, so it is added 
                       #    and a new list is the value 
>>> result
defaultdict(<type 'list'>, {'a': [], 'c': [], 'b': []})
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用.updateRaymond Hettinger指出的方法:

>>> result=defaultdict(list)
>>> result.update((k,[]) for k in 'abc')
>>> result
defaultdict(<type 'list'>, {'a': [], 'c': [], 'b': []})  
Run Code Online (Sandbox Code Playgroud)

或者,正如ivan_pozdeev评论中指出的那样,您可以执行以下操作:

>>> di=defaultdict(list,{k:[] for k in 'abc'})
>>> di
defaultdict(<type 'list'>, {'a': [], 'c': [], 'b': []})  
Run Code Online (Sandbox Code Playgroud)

或者,您可以使用带有 dict 理解的常规 Python dict 来获得相同的结果——不需要 defaultdict——如果您只需要或想要这三个具有唯一列表的键作为它们的值:

>>> di={k:[] for k in 'abc'}
>>> di
{'a': [], 'c': [], 'b': []}
Run Code Online (Sandbox Code Playgroud)

这些是每个键的单独列表:

>>> di['a'].append(1)
>>> di
{'a': [1], 'c': [], 'b': []}
Run Code Online (Sandbox Code Playgroud)

一个常见的错误(我犯了;-0)是使用类似的东西.fromkeys并获得多个键引用的相同列表:

>>> di2={}.fromkeys(['a','b','c'], [])
>>> di2
{'a': [], 'c': [], 'b': []}      # looks ok
>>> di2['a'].append('WRONG!')
>>> di2
{'a': ['WRONG!'], 'c': ['WRONG!'], 'b': ['WRONG!']}
Run Code Online (Sandbox Code Playgroud)

发生是因为所有键都引用了同一个列表。

  • 你忘了你可以使用构造函数在一个表达式中创建完整的对象:`collections.defaultdict(&lt;默认值生成器未指定由 OP&gt;,{k:[] for k in 'abc'})` (2认同)