TypeError:“dict_keys”对象不支持索引
Posted
技术标签:
【中文标题】TypeError:“dict_keys”对象不支持索引【英文标题】:TypeError: 'dict_keys' object does not support indexing 【发布时间】:2013-06-23 17:53:35 【问题描述】:def shuffle(self, x, random=None, int=int):
"""x, random=random.random -> shuffle list x in place; return None.
Optional arg random is a 0-argument function returning a random
float in [0.0, 1.0); by default, the standard random.random.
"""
randbelow = self._randbelow
for i in reversed(range(1, len(x))):
# pick an element in x[:i+1] with which to exchange x[i]
j = randbelow(i+1) if random is None else int(random() * (i+1))
x[i], x[j] = x[j], x[i]
当我运行shuffle
函数时,它会引发以下错误,这是为什么呢?
TypeError: 'dict_keys' object does not support indexing
【问题讨论】:
好像是python3的错误 【参考方案1】:很明显,您将d.keys()
传递给您的shuffle
函数。可能这是用 python2.x 编写的(当d.keys()
返回一个列表时)。在 python3.x 中,d.keys()
返回一个 dict_keys
对象,它的行为更像 set
而不是 list
。因此,它无法被索引。
解决方案是将list(d.keys())
(或简单的list(d)
)传递给shuffle
。
【讨论】:
。 . .或者只是list(d)
,它将为您提供 python2.x 和 python3.x 上的键列表,而无需制作任何副本 :-)
对于 python3,这是一个奇怪的重大变更设计决策。
您可能会这么认为,但我绝对认为这是正确的决定。 dict_keys
对象的行为更像是字典的一半键。具体来说,它们支持 O(1) 成员资格测试(以及其他可以在该事实之上有效实现的类似集合的方法)。这些事情是不可能用列表实现的,如果你想要一个字典键的列表,你总是可以简单地通过list(your_dictionary)
来获得它。
这有助于我看到python3要求我们用列表包装字典。
@Crt -- shuffle
是原始发布者代码中的函数名称(引发错误的函数)。查看代码,我认为它是从random.shuffle
在标准库中的实现中复制/粘贴的:-)【参考方案2】:
您将somedict.keys()
的结果传递给函数。在 Python 3 中,dict.keys
不返回一个列表,而是一个表示字典键视图的类集合对象,并且(像集合一样)不支持索引。
要解决此问题,请使用 list(somedict.keys())
收集密钥并使用它。
【讨论】:
【参考方案3】:将可迭代对象转换为列表可能会产生成本。相反,要获取第一项,您可以使用:
next(iter(keys))
或者,如果您想遍历所有项目,您可以使用:
items = iter(keys)
while True:
try:
item = next(items)
except StopIteration as e:
pass # finish
【讨论】:
OP 不想只想访问第一个项目或一次迭代这些项目,他们需要随机访问项目以随机播放它们。有了这些要求,将可迭代对象转换为列表正是正确的方法。此外,您的第二个 sn-p 可以替换为更清晰、更高效的for item in keys: pass
。【参考方案4】:
在 Python 2 中 dict.keys() 返回一个列表,而在 Python 3 中它返回一个生成器。
您只能迭代它的值,否则您可能必须将其显式转换为列表,即将其传递给列表函数。
【讨论】:
【参考方案5】:为什么在已经存在的情况下需要实现 shuffle?站在巨人的肩膀上。
import random
d1 = 0:'zero', 1:'one', 2:'two', 3:'three', 4:'four',
5:'five', 6:'six', 7:'seven', 8:'eight', 9:'nine'
keys = list(d1)
random.shuffle(keys)
d2 =
for key in keys: d2[key] = d1[key]
print(d1)
print(d2)
【讨论】:
答案与一般知识相关,但与 OP 的要求无关。 你是对的。看来他想实现自己的随机化器。 psah,也许他实际上并不知道他可以使用内置,但问题实际上似乎与类型错误有关。不过,我希望他转换并使用您的选项(除非它是非常具体的)来遵循基本的 DRY 和代码经济原则。以上是关于TypeError:“dict_keys”对象不支持索引的主要内容,如果未能解决你的问题,请参考以下文章
如何更正错误“AttributeError: 'dict_keys' object has no attribute 'remove'”?
ValueError: (‘Unexpected parameters in params‘, dict_keys([‘cv‘]))
ValueError: (‘Unexpected parameters in params‘, dict_keys([‘cv‘]))
ValueError: ('Unrecognized keyword arguments:', dict_keys(['ragged'])) while loading keras model