Подтвердить что ты не робот

Ошибка 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'], если я не схожу с ума.

Что происходит?

4b9b3361

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