带有字典作为容器的python字典奇怪的行为

时间:2019-06-26 02:03:53

标签: python python-2.7 dictionary

这是问题的简化代码段

>>> dict ({'A': 58, 'B': 130} for _ in range(1))
{'A': 'B'}

我希望它返回传入的相同字典。

如果我愿意

>>> dict({'A': 58, 'B': 130})

我得到的正是我想要的东西,那就是 {'A': 58, 'B': 130}

为什么这种行为与众不同,如何解决? 我无法在此处更改表达式,但可以按自己喜欢的方式更改输入字典,例如,可以像[{'A': 58, 'B': 130}]

4 个答案:

答案 0 :(得分:5)

一个dict可以用另一个dict或可迭代的成对初始化,这就是您所给的。请注意,对字典进行迭代只会产生其键。

>>> d = {'A': 58, 'B': 130}
>>> list(d)
['A', 'B']
>>> dict([('A', 'B'), ('C', 'D')])
{'A': 'B', 'C': 'D'}
>>> dict([d, ('C', 'D')])
{'A': 'B', 'C': 'D'}

Python的行为完全符合规定。您的字典恰好是一对。

答案 1 :(得分:2)

您要传递的字典有一些特殊之处... ({'A': 58, 'B': 130} for _ in range(1))表示长度为1的生成器序列。您传递的内容类似于

dict([{'A': 58, 'B': 130}])
# {'A': 'B'}

另一方面,这些将不起作用:

dict([{'A':58}])
# ValueError: dictionary update sequence element #0 has length 1; 2 is required

dict([{'A':58, 'B': 130, 'C': 150}])    
ValueError: dictionary update sequence element #0 has length 3; 2 is required

第一个示例之所以有效,是因为您的字典中有 个正好两个条目

序列被传递到dict方法,该方法接受创建键值对所需的两个项目,并创建一个像这样的字典:

{'A': 'B'}

IOW,它需要一个成对的可迭代对象,这就是具有两个条目的单个字典的序列。其他任何东西都会抛出ValueError

答案 2 :(得分:1)

因为它将简单地与['A', 'B']一起制成list

>>> list({'A': 58, 'B': 130})
['A', 'B']
>>> 

由于是字典列表,因此在dict中进行迭代,因此对所有字典都将其设为list,所以:

>>> dict([{'A': 58, 'B': 130}])
{'A': 'B'}
>>> dict({'A': 58, 'B': 130})
{'A': 58, 'B': 130}
>>> 

此外,如果没有dict,它将为字典列表执行以下操作:

>>> {*{'A': 58, 'B': 130}}
{'A', 'B'}
>>> 

只是像字典一样,但是您现在应该获取它。

答案 3 :(得分:1)

{'A': 58, 'B': 130} for _ in range(1)会产生[{'A': 58, 'B': 130}],因此您要向dict()传递列表,而不是字典。

根据文档,如果将迭代器传递给dict(),则可以有效地获得:

d = {}
for k, v in iterable:
   d[k] = v

由于列表中的dict正好有两个元素,因此for k,v in iterable:循环将获得dict中的前两个键。如果dict只有一个元素或多于两个元素,那么您会得到ValueError