Вот упрощенный фрагмент кода проблемы

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

Я ожидаю, что он вернет тот же словарь, который был передан.

Если я сделаю

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

Я получаю именно то, что ищу, то есть {{Х0}}

Почему это поведение отличается, как это исправить? Я не могу изменить выражение там, но я могу изменить словарь ввода любым способом, который мне нравится, например, я могу передать его как [{'A': 58, 'B': 130}]

2
joe 26 Июн 2019 в 05:03

4 ответа

Лучший ответ

{'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.

1
John Gordon 26 Июн 2019 в 02:14

Есть что-то особенное в передаваемом вами дикте ... ({'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'}

Итак, для этого требуется итерируемая пара, какова ваша последовательность с одним указанием из двух записей. Все остальное выльется ValueError.

2
cs95 26 Июн 2019 в 02:13

Диктовка может быть инициализирована другой, или итерируемой парой, что вы и дали. Обратите внимание, что итерация по 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 ведет себя точно так, как указано. Ваш диктат оказался парой.

5
gilch 26 Июн 2019 в 02:10

Потому что он просто сделает это ['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'}
>>> 

Просто словарным способом, но вы должны получить это сейчас.

1
U10-Forward 26 Июн 2019 в 02:13