Get: TypeError: объект dict_values не поддерживает индексирование при использовании python 3.2.3
Это мой код:
{names[i]:d.values()[i] for i in range(len(names))}
Это отлично работает при использовании python 2.7.3; однако, когда я использую python 3.2.3, я получаю сообщение об ошибке 'dict_values' object does not support indexing
. Как я могу изменить код, чтобы сделать его совместимым для 3.2.3?
Ответы
Ответ 1
В Python 3, dict.values()
(вместе с dict.keys()
и dict.items()
) возвращает view
, а не список. См. Документацию здесь. Поэтому для вызова dict.values()
для вызова list
необходимо:
v = list(d.values())
{names[i]:v[i] for i in range(len(names))}
Ответ 2
Простейшая версия вашего кода:
dict(zip(names, d.values()))
Если вы хотите сохранить ту же структуру, вы можете изменить ее на:
vlst = list(d.values())
{names[i]: vlst[i] for i in range(len(names))}
(Вы можете так же легко положить list(d.values())
внутри понимания, а не vlst
, это просто расточительно, потому что он будет перегенерировать список каждый раз).
Ответ 3
В Python 3 метод dict.values()
возвращает объект представления словаря, а не список, как в Python 2. dict.values()
словаря имеют длину, могут быть повторены и поддерживать проверку членства, но не поддерживают индексацию.
Чтобы ваш код работал в обеих версиях, вы можете использовать любую из них:
{names[i]:value for i,value in enumerate(d.values())}
или же
values = list(d.values())
{name:values[i] for i,name in enumerate(names)}
Безусловно, самый простой и быстрый способ сделать то же самое в любой версии:
dict(zip(names, d.values()))
Обратите внимание, что все эти методы будут давать вам результаты, которые будут варьироваться в зависимости от фактического содержания d
. Чтобы преодолеть это, вы можете вместо этого использовать OrderedDict, который запоминает порядок, в который ключи были сначала вставлены в него, так что вы можете рассчитывать на порядок того, что возвращается методом values()
.