简体   繁体   English

用dict作为容器的python字典奇怪的行为

[英]python dictionary weird behavior with dict as container

Here is a simplified code snippet of the problem 这是问题的简化代码片段

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

I am expecting it to return the same dictionary passed in. 我期待它返回传入的相同字典。

if I do 如果我做

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

I get exactly what I am looking for, that is {'A': 58, 'B': 130} 我得到了我正在寻找的东西,即{'A': 58, 'B': 130}

Why is this behavior different, how to fix it? 为什么这种行为有所不同,如何解决? I cannot alter the expression there, but I can alter the input dictionary in whatever way I like, for example, I can pass it like [ {'A': 58, 'B': 130}] 我无法改变那里的表达,但我可以用我喜欢的任何方式改变输入字典,例如,我可以像[ {'A': 58, 'B': 130}]那样传递它

A dict can be initialized with another dict, or with an iterable of pairs, which is what you have given it. 一个字典可以用另一个字典初始化,或者用一对可迭代的字符串初始化,这就是你给它的。 Note that iterating over a dict yields its keys only. 请注意,迭代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 is behaving exactly as specified. Python的行为完全符合指定。 Your dict happens to be a pair. 你的dict碰巧是一对。

There's something special about the dict you're passing... ({'A': 58, 'B': 130} for _ in range(1)) represents a generator sequence of length 1. What you are passing is similar to 关于你传递的词典有一些特别的东西...... ({'A': 58, 'B': 130} for _ in range(1))表示长度为1的生成器序列。你传递的是什么类似于

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

These, on the other hand, will not work: 另一方面,这些将不起作用:

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

The first example worked because your dictionary had exactly two entries . 第一个例子有效,因为你的字典只有两个条目

The sequence is passed to the dict method, which takes the two items it needs to create a key-value pair, and creates a dictionary like this: 序列被传递给dict方法,该方法获取创建键值对所需的两个项目,并创建如下字典:

{'A': 'B'}

IOW, it requires an iterable of pairs, which is what your sequence with a single dict of two entries is. IOW,它需要一对可迭代的对,这是你的序列与两个条目的单个dict。 Anything else will throw a ValueError . 其他任何东西都会抛出一个ValueError

Because it simply will make it ['A', 'B'] , with list as well: 因为它只会使它成为['A', 'B'] ,也带有list

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

And since it iterates in dict since it's a list of dictionaries, it would make it list for all of them, so: 并且由于它是dict迭代,因为它是一个字典列表,它会list所有字典,所以:

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

Also, without dict it would be doing something like the below for a list of dictionaries: 此外,没有dict它会像下面的字典列表一样:

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

Just in a dictionary-like way, but you should get it now. 只是以字典的方式,但你现在应该得到它。

{'A': 58, 'B': 130} for _ in range(1) yields [{'A': 58, 'B': 130}] , therefore you are passing a list, not a dict, to dict() . {'A': 58, 'B': 130} for _ in range(1)产生[{'A': 58, 'B': 130}] ,因此你将一个列表而不是一个字典传递给dict()

According to the documentation, if you pass an iterable to dict() , you effectively get: 根据文档,如果你将一个iterable传递给dict() ,你有效地得到:

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

Since the dict inside the list has exactly two elements, the for k,v in iterable: loop gets the first two keys in the dict. 由于列表中的dict恰好有两个元素, for k,v in iterable: loop获取dict中的前两个键。 If the dict had only one element, or more than two, you would get a ValueError . 如果dict只有一个元素,或者只有两个元素,那么你会得到一个ValueError

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM