Python字典.keys()错误

42 投票
5 回答
91180 浏览
提问于 2025-04-17 10:46

我正在尝试使用 .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 个回答

2

这是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)本身是无序的,而且它的键是唯一的——这和集合(set)很像。

这个变化意味着你不需要每次想要和字典的键进行集合比较时,都去创建一个新的键列表。

在Python 2和3中获得相同的行为

为了帮助大家过渡到Python 3,Python 2.7增加了一个新的字典方法,叫做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']

或者直接把字典传给list,因为字典本身会遍历它的键:

>>> list(d)
['d', 'a', 'c', 'b']

你还可以创建一个工具函数来统一处理Python 2和3中的这种行为:

if hasattr(dict, 'viewkeys'): # Python 2.7
    def keys(d):
        return d.viewkeys()
else:  # Python 3
    def keys(d):
        return d.keys()

然后把字典传给list,这样在Python 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']
8

如果你这样给 k 赋值:

k = list(b.keys())

你的代码就能正常运行了。

正如错误信息所说,dict_keys 这种类型是不支持索引的。

91

在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']

撰写回答