Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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}

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}]

like image 666
joe Avatar asked Apr 19 '26 17:04

joe


2 Answers

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.

>>> 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. Your dict happens to be a pair.

like image 90
gilch Avatar answered Apr 22 '26 05:04

gilch


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

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:

{'A': 'B'}

IOW, it requires an iterable of pairs, which is what your sequence with a single dict of two entries is. Anything else will throw a ValueError.

like image 40
cs95 Avatar answered Apr 22 '26 05:04

cs95