如果有重复的键,python 字典理解总是 "last wins"

Is a python dict comprehension always "last wins" if there are duplicate keys

如果我创建一个带有字典理解的 python 字典,但有重复的键,我能保证最后一项将是最终字典中的那个吗?通过查看 https://www.python.org/dev/peps/pep-0274/?

我不清楚
new_dict = {k:v for k,v in [(1,100),(2,200),(3,300),(1,111)]}
new_dict[1] #is this guaranteed to be 111, rather than 100?

如果你的意思是

{key: val for (key, val) in pairs}

其中 pairs 是 2 元素列表或元组的有序集合(例如,列表或元组)然后是的,理解将按顺序获取集合,最后一个值将 "win" .

注意,如果 pairs 是一组对,那么就没有 "last item",所以结果是不可预测的。 示例:

>>> n = 10
>>> pairs = [("a", i) for i in range(n)]
>>> {key:val for (key, val) in pairs}
{'a': 9}
>>> {key:val for (key, val) in set(pairs)}
{'a': 2}

键的最后一个值获胜。我能找到的最好的文档在 Python 3 language reference, section 6.2.7:

A dict comprehension, in contrast to list and set comprehensions, needs two expressions separated with a colon followed by the usual “for” and “if” clauses. When the comprehension is run, the resulting key and value elements are inserted in the new dictionary in the order they are produced.

该文档还明确指出,最后一项适用于逗号分隔的键值对 ({1: 1, 1: 2}) 和字典解包 ({**{1: 1}, **{1: 2}}):

If a comma-separated sequence of key/datum pairs is given, ... you can specify the same key multiple times in the key/datum list, and the final dictionary’s value for that key will be the last one given.

A double asterisk ** denotes dictionary unpacking. Its operand must be a mapping. Each mapping item is added to the new dictionary. Later values replace values already set by earlier key/datum pairs and earlier dictionary unpackings.

请注意 ,如果有相同但不同的密钥,则密钥的第一个版本获胜:

>>> {k: v for k, v in [(1, 1), (1.0, 2.0)]}
{1: 2.0}

这里,最终的字典有来自 (1, 1) 的键,但是来自 (1.0, 2.0).

的值

am I guaranteed that the last item will the the one that ends up in the final dictionary?

不完全是...

在重复键的情况下,第一个键被保留,最后一个值被保留。结果 item (key, value) 一开始可能不存在于任何原始对中。

>>> {1.0: 1, 1: 1.0}
{1.0: 1.0}

此行为在 Dictionary displays 下有所记录(强调我的):

This means that you can specify the same key multiple times in the key/datum list, and the final dictionary’s value for that key will be the last one given.