Понимание словаря приводит к неожиданному результату - PullRequest
0 голосов
/ 07 сентября 2018

Я изучаю Python, в настоящее время понимание словаря. Я играю с разными идеями, просто чтобы увидеть, что я получаю, и я получаю ту, которую я действительно не понимаю. Любая помощь в понимании того, что я делаю неправильно, будет очень признательна.

В частности, этот код:

test_dict = {key: val
        for key in ['a','b','c']
        for val in range(3)}
print(test_dict)

Создает следующий словарь: {'a': 2, 'b': 2, 'c': 2}

Я ожидаю: {'a': 0, 'b': 1, 'c': 2}

Когда я запускаю этот быстрый цикл:

for val in range(3):
   print(val)

Я получаю:

0
1
2

Существует ли причина, по которой каждый ключ словаря получает одно и то же значение, окончательное значение итератора диапазона?

Я использую Python 3.6.5 через ноутбуки Anaconda / Jupyter.

Ответы [ 2 ]

0 голосов
/ 07 сентября 2018

Ваш код эквивалентен 2 вложенным циклам for, для каждого key вы эффективно выполняете последовательно команду test_dict[key] = val для всех val, останется только последний.

Вы, вероятно, хотите вместо этого:

test_dict = {key: val for key,val in zip('abc', range(3))}

или напрямую

test_dict = dict(zip('abc', range(3)))
0 голосов
/ 07 сентября 2018

Давайте взорвем ваше понимание диктата; это эквивалентно следующему:

test_dict = {}
for key in ['a','b','c']:
    for val in range(3):
        test_dict[key] = val

Итак, для каждого ключа вы выполняете три разных назначения в своем словаре. Естественно, сохраняется только последний.

Чтобы получить желаемый результат, просто назначьте ho для каждой клавиши один раз. Очевидный способ в этом случае - использовать enumerate() для нумерации элементов в последовательности, а затем использовать это значение.

test_dict = {key: val for val, key in enumerate(['a','b','c'])}

Для общего случая любых двух последовательностей используйте zip():

test_dict = {key: val for key, val in zip(['a', 'b', 'c'], range(3))}

На самом деле, поскольку конструктор dict рад использовать последовательность пар ключ / значение, вы можете написать это так:

test_dict = dict(zip(['a', 'b', 'c'], range(3)))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...