找到你要的答案

Q:Python 3 map dictionary update method to a list of other dictionaries [duplicate]

Q:Python 3地图字典更新方法列出其他词典[复制]

This question already has an answer here:

In Python 2 I can do the following:

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

In Python 3 in get a KeyError:

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

I would like to achieve the same behavior in Python 3 as in Python 2.

I understand that map in Python 3 will return an iterator (lazy evaluation and whatnot), which has to be iterated for the dictionary to be updated.

I had assumed the d['c'] key lookup would trigger the map iteration somehow, which is not the case.

Is there a pythonic way to achieve this behavior without writing a for loop, which I find to be verbose compared to map.

I have thought of using list comprehensions:

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

But it does not seem pythonic.

这个问题在这里已经有了答案:

在Python 2我可以做如下:

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

在Python 3中得到一个KeyError:

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

我想实现在Python 3相同的行为在Python 2。

我的理解是,地图在Python 3将返回一个迭代器(懒惰的评价等等),这是迭代字典进行更新。

我觉得D [ C ]键查找会触发地图迭代在某种程度上,这是不是这样的。

Is there a pythonic way to achieve this behavior without writing a for loop, which I find to be verbose compared to map.

我已经使用列表解析思想:

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

但它似乎没有语言。

answer1: 回答1:

As you note, map in Python 3 creates an iterator, which doesn't (in and of itself) cause any updates to occur:

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

To force the map to be fully evaluated, you could pass it to list explicitly:

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

However, as the relevant section of What's new in Python 3 puts it:

Particularly tricky is map() invoked for the side effects of the function; the correct transformation is to use a regular for loop (since creating a list would just be wasteful).

In your case, this would look like:

for extra in extras:
    d.update(extra)

which doesn't result in an unnecessary list of None.

你注意,地图在Python 3中创建一个迭代器,它不(本身)造成任何更新发生:

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

若要强制将地图完全求值,则可以将其显式传递给列表:

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

然而,由于相关部门有什么新的Python 3把:

Particularly tricky is map() invoked for the side effects of the function; the correct transformation is to use a regular for loop (since creating a list would just be wasteful).

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

for extra in extras:
    d.update(extra)

这不会导致不必要的列表。

answer2: 回答2:

Alongside the @jonrsharpe's explanation that explains the problem clearly In Python 3 you can use collections.ChainMap for such tasks:

>>> from collections import ChainMap
>>> chain=ChainMap(d, *extras)
>>> chain
ChainMap({'a': 1}, {'b': 2}, {'c': 4})
>>> chain['c']
4

But note that if there are duplicate keys, the values from the first mapping get used.

Read more about the advantages of using ChainMap :What is the purpose of collections.ChainMap?

在“jonrsharpe的解释,解释清楚的问题在Python 3中你可以使用collections.chainmap等任务:

>>> from collections import ChainMap
>>> chain=ChainMap(d, *extras)
>>> chain
ChainMap({'a': 1}, {'b': 2}, {'c': 4})
>>> chain['c']
4

但请注意,如果有重复键,第一映射的值将被使用。

阅读更多关于使用chainmap优点:collections.chainmap的目的是什么?

python  python-2.7  python-3.x  dictionary