Python 3将地图字典更新方法更新为其他字典列表

mat*_*thu 9 python dictionary python-2.7 python-3.x map-function

在Python 2中,我可以执行以下操作:

>> d = {'a':1}
>> extras = [{'b':2}, {'c':4}]
>> map(d.update, extras)
>> d['c']
>> 4
Run Code Online (Sandbox Code Playgroud)

在Python 3中得到一个KeyError:

>> d = {'a':1}
>> extras = [{'b':2}, {'c':4}]
>> map(d.update, extras)
>> d['c']
>> KeyError: 'c'
Run Code Online (Sandbox Code Playgroud)

我想在Python 3中实现与Python 2中相同的行为.

我知道Python 3中的map将返回一个迭代器(lazy evaluation和whatnot),必须迭代它才能更新字典.

我假设d['c']密钥查找会以某种方式触发映射迭代,但事实并非如此.

有没有pythonic方法来实现这种行为而不编写for循环,我发现与map相比,它是冗长的.

我想过使用列表推导:

>> d = {'a':1}
>> extras = [{'b':2}, {'c':4}]
>> [x for x in map(d.update, extras)]
>> d['c']
>> 4
Run Code Online (Sandbox Code Playgroud)

但它似乎并不像pythonic.

jon*_*rpe 7

正如您所注意到的,map在Python 3中创建了一个迭代器,它不会(在其自身中)导致任何updates发生:

>>> d = {'a': 1}
>>> extras = [{'b':2}, {'c':4}]
>>> map(d.update, extras)
<map object at 0x105d73c18>
>>> d
{'a': 1}
Run Code Online (Sandbox Code Playgroud)

要强制map进行完全评估,可以将其list明确传递给:

>>> list(map(d.update, extras))
[None, None]
>>> d
{'a': 1, 'b': 2, 'c': 4}
Run Code Online (Sandbox Code Playgroud)

但是,正如Python 3中的新功能的相关部分所述:

特别棘手的是map()函数的副作用; 正确的转换是使用常规for循环(因为创建列表只会浪费).

在您的情况下,这将看起来像:

for extra in extras:
    d.update(extra)
Run Code Online (Sandbox Code Playgroud)

这不会导致不必要的列表None.

  • 注意:除了“list”之外,还可以使用“collections.deque(iterable, maxlen=0)”来使用“iterable”而不消耗内存。这也只执行一个字节码,因此至少在 CPython 中应该比显式的“for”稍微节省时间。 (2认同)