我正在尝试使用.keys()
and 而不是像过去一样获取键列表。但是我明白了。
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'] 除非我快疯了。
这是怎么回事?
我正在尝试使用.keys()
and 而不是像过去一样获取键列表。但是我明白了。
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'] 除非我快疯了。
这是怎么回事?
Python 3 改变了dict.keys
这样的行为,它现在返回一个dict_keys
可迭代但不可索引的对象(就像 old 一样dict.iterkeys
,现在已经不存在了)。您可以通过显式调用返回 Python 2 结果list
:
>>> b = { 'video':0, 'music':23 }
>>> k = list(b.keys())
>>> k
['music', 'video']
要不就
>>> list(b)
['music', 'video']
如果你k
这样分配:
k = list(b.keys())
您的代码将起作用。
正如错误所说,该dict_keys
类型不支持索引。
这是 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 的键进行某种集合比较时都创建新的键列表。
为了帮助过渡到 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']
如果您只是想要字典中的键列表,您可以直接这样做:
b = {"name": "xyz", "class":"abc", "college": "qwert"}
key_list = list(b)
key_list 将包含所有键名作为一个列表,但是,如果发现不止一次,这不会重复一个键。重复的键将被计为一个。
import random
b = { 'video':0, 'music':23,"picture":12 }
random.choice(tuple(b.items()))
# Returns a random dictionary entry as a tuple:
# ('music', 23)