Ошибка Python dictionary.keys()
Я пытаюсь использовать .keys()
и вместо того, чтобы получать список ключей вроде
всегда в прошлом. Однако я получаю это.
b = { 'video':0, 'music':23 }
k = b.keys()
print( k[0] )
>>>TypeError: 'dict_keys' object does not support indexing
print( k )
dict_keys(['music', 'video'])
он должен просто напечатать ['music', 'video'], если я не схожу с ума.
Что происходит?
Ответы
Ответ 1
Python 3 изменил поведение dict.keys
таким образом, что теперь он возвращает объект dict_keys
, который является итерируемым, но не индексируемым (он похож на старый dict.iterkeys
, который теперь ушел). Вы можете вернуть результат Python 2 с явным вызовом list
:
>>> b = { 'video':0, 'music':23 }
>>> k = list(b.keys())
>>> k
['music', 'video']
или просто
>>> list(b)
['music', 'video']
Ответ 2
Если вы назначили k
следующим образом:
k = list(b.keys())
ваш код будет работать.
Как говорится в ошибке, тип dict_keys
не поддерживает индексирование.
Ответ 3
Это одно из основных изменений между Python 2 и 3.
В Python 2:
>>> help(dict.keys)
keys(...)
D.keys() -> list of D keys
В Python 3:
>>> help(dict.keys)
keys(...)
D.keys() -> a set-like object providing a view on D keys
Это изменение в поведении имеет большой смысл, поскольку dict семантически неупорядочен и его ключи уникальны - как набор.
Это изменение означает, что вам не нужно создавать новый список ключей каждый раз, когда вы хотите выполнить какое-то сравнение с ключами.
Получение одинакового поведения в 2 и 3
Чтобы перейти на Python 3, Python 2.7 имеет другой метод dict, viewkeys
. Метод viewkeys
наиболее похож на метод Python 3 dict.keys
:
>>> d
{'a': None, 'c': None, 'b': None, 'd': None}
>>> for k in d.viewkeys(): print k
...
a
c
b
d
>>> d.viewkeys() & set('abc')
set(['a', 'c', 'b'])
В Python 3 наиболее близким аналогом старого поведения является передача dict.keys()
в list
:
>>> d
{'d': None, 'a': None, 'c': None, 'b': None}
>>> list(d.keys())
['d', 'a', 'c', 'b']
Или просто передайте dict на list
, так как dict будет итерации по своим клавишам:
>>> list(d)
['d', 'a', 'c', 'b']
Вы можете создать функции утилиты для абстрактного поведения над 2 и 3:
if hasattr(dict, 'viewkeys'): # Python 2.7
def keys(d):
return d.viewkeys()
else: # Python 3
def keys(d):
return d.keys()
И передайте dict на list
, чтобы получить форму списка, а в обоих и в 2 и 3 вы получите тот же результат:
>>> d
{'b': None, 'a': None, 'c': None, 'd': None}
>>> keys(d)
dict_keys(['b', 'a', 'c', 'd'])
>>> list(d)
['b', 'a', 'c', 'd']
Ответ 4
Если вам просто нужен список ключей из словаря, вы можете сделать это следующим образом:
b = {"name": "xyz", "class":"abc", "college": "qwert"}
key_list = list(b)
key_list будет содержать все имена ключей в виде списка, однако это не будет повторять ключ, если он найден более одного раза. Дублируемые ключи будут считаться как один.