Почему все значения этого словаря одинаковы?

#python #dictionary #dictionary-comprehension

#python #словарь #понимание словаря

Вопрос:

Я пытаюсь написать это понимание словаря, и я не знаю, почему все значения словаря одинаковы.

Код:

 from string import ascii_uppercase

dictionary = {key: value for key in range(0, len(ascii_uppercase)) for value in ascii_uppercase}
 

Результат:

 {0: 'Z', 1: 'Z', 2: 'Z', 3: 'Z', 4: 'Z', 5: 'Z', 6: 'Z', 7: 'Z', 8: 'Z', 9: 'Z', 10: 'Z', 11: 'Z', 12: 'Z', 13: 'Z', 14: 'Z', 15: 'Z', 16: 'Z', 17: 'Z', 18: 'Z', 19: 'Z', 20: 'Z', 21: 'Z', 22: 'Z', 23: 'Z', 24: 'Z', 25: 'Z'}
 

Почему он выдает мне только последний символ строки в качестве всех значений?
Как я могу это исправить?

Комментарии:

1. В основном он выполняется 26 раз до конца

2. Когда у вас есть несколько for x in операторов в понимании, они являются вложенными , причем крайнее правое выражение является самым внешним циклом. При окончательном выполнении внешнего цикла value он равен Z, а затем внутренний цикл присваивает каждому ключу это значение.

Ответ №1:

Если вы преобразуете понимание dict в обычные циклы, у вас есть это:

 dictionary = {}
for key in range(0, len(ascii_uppercase)): # for every number in range 0-26
    for value in ascii_uppercase:          # for every letter in range a-z
        dictionary[key] = value            # d[num] = letter
 

Последняя буква для каждого числа — это 'z' то, что ваш словарь обновляется ею в конце внутреннего цикла для каждого числа.

Вы можете попробовать:

 di = {}
for i, letter in enumerate(ascii_uppercase):
    di[i] = letter
 

или

 di = {i: letter for i, letter in enumerate(ascii_uppercase)}
 

или

 di = dict(enumerate(ascii_uppercase))
 

Комментарии:

1. во-первых, я хочу использовать понимание, а не обычные циклы, а во-вторых, что, если я хочу каким-то образом связать два разных списка и написать понимание словаря?

2. Во-первых, циклы предназначены для того, чтобы помочь вам понять, что вы на самом деле делаете, а во-вторых, вы, вероятно, будете искать zip , но enumerate это гораздо более простой и более питонический способ сделать это.

Ответ №2:

Поскольку внутренний цикл всегда заканчивается как конец списка, enumerate() dict() для этого лучше использовать with:

 dictionary = dict(enumerate(ascii_uppercase))
 

Комментарии:

1. Я не понизил голос, но это не отвечает на вопрос о том, почему это происходит

2. @Chris добавил объяснение

3. Я также не понизил голос, но зачем беспокоиться о a dict , когда последовательности уже имеют индексацию?

4. @ekhumoro мы делаем то, для чего OP хочет его исправить.

5. @ekhumoro зачем спрашивать об этом меня, спросите об этом у OP? (Ы) Он может хотеть этого по какой-либо конкретной причине

Ответ №3:

Второй цикл for полностью выполняется перед первым, поэтому он портит результат. Вместо этого вы можете попробовать этот подход только с одним циклом for:

 dictionary = {i: ascii_uppercase[i] for i in range(len(ascii_uppercase))}
 

Комментарии:

1. Если бы у Хасана было более элегантное решение, я бы, вероятно, придерживался этого 🙂

Ответ №4:

Измените свой код на это

 from string import ascii_uppercase

dictionary = {key: value for key,value in enumerate(ascii_uppercase, 0)}
 

Вывод

 {0: 'A', 1: 'B', 2: 'C', 3: 'D', 4: 'E', 5: 'F', 6: 'G', 7: 'H', 8: 'I', 9: 'J', 10: 'K', 11: 'L', 12: 'M', 13: 'N', 14: 'O', 15: 'P', 16: 'Q', 17: 'R', 18: 'S', 19: 'T', 20: 'U', 21: 'V', 22: 'W', 23: 'X', 24: 'Y', 25: 'Z'}
 

Ответ №5:

Хотя есть и другие подходящие ответы, я считаю, что это то, что вы думаете, что делаете.

 from string import ascii_uppercase


{key: value for key,value in zip(range(0, len(ascii_uppercase)),ascii_uppercase)}