Python dictionary.keys () ошибка - PullRequest
42 голосов
/ 21 января 2012

Я пытаюсь использовать .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'], если я не схожу с ума.

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

Ответы [ 5 ]

91 голосов
/ 21 января 2012

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']
8 голосов
/ 21 января 2012

Если вы присвоили k, например, так:

k = list(b.keys())

ваш код будет работать.

Как говорится в ошибке, тип dict_keys не поддерживает индексирование.

2 голосов
/ 01 января 2016

Это одно из критических изменений между Python 2 и 3.

В Python 2:

>>> help(dict.keys)
keys(...)
    D.keys() -> list of D's keys

В Python 3:

>>> help(dict.keys)
keys(...)
    D.keys() -> a set-like object providing a view on D's keys

Это изменениев поведении много смысла, так как dict семантически неупорядочен, а его ключи уникальны - как набор.

Это изменение означает, что вам не нужно создавать новый список ключей каждый раз, когда вы хотите выполнить какое-то сравнение наборов с ключами dict.

Получение того же поведения в 2и 3

Чтобы помочь переходу на Python 3, в Python 2.7 есть еще один метод dict, viewkeys.Метод viewkeys наиболее похож на метод dict.keys в Python 3:

>>> 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']
0 голосов
/ 18 января 2018
import random
b = { 'video':0, 'music':23,"picture":12 }
random.choice(tuple(b.items()))

# Returns a random dictionary entry as a tuple:
# ('music', 23)
0 голосов
/ 30 января 2017

Если вы просто хотите получить список ключей из словаря, вы можете сделать это следующим образом:

b = {"name": "xyz", "class":"abc", "college": "qwert"}  
key_list = list(b)

key_list будет содержать все имена ключей в виде списка, хотя это не будет повторять ключ,если найдено более одного раза.Дублирующиеся ключи будут считаться одним.

...