Python 类型错误:';dict#u键';对象不支持索引

Python 类型错误:';dict#u键';对象不支持索引,python,python-3.x,dictionary,Python,Python 3.x,Dictionary,当我运行shuffle函数时,它会引发以下错误,这是为什么 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 defa

当我运行shuffle函数时,它会引发以下错误,这是为什么

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]

显然,您正在将
d.keys()
传递给
shuffle
函数。这可能是用python2.x编写的(当
d.keys()
返回一个列表时)。在python3.x中,
d.keys()
返回一个
dict\u keys
对象,它的行为更像一个
集合,而不是一个
列表。因此,它不能被索引


解决方案是将
list(d.keys())
(或者简单地
list(d)
)传递给
shuffle

,您正在将
somedict.keys()
的结果传递给函数。在Python3中,
dict.keys
不返回列表,但表示字典键视图的set-like对象(设置为like)不支持索引


要解决此问题,请使用
list(somedict.keys())
收集密钥,然后使用它。

为什么需要在密钥已经存在的情况下实现shuffle?站在巨人的肩膀上

TypeError: 'dict_keys' object does not support indexing

将iterable转换为列表可能会产生成本。相反,要获取第一个项目,您可以使用:

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)
next(iter(keys))
或者,如果要迭代所有项目,可以使用:

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)
next(iter(keys))
在Python 2中,dict.keys()返回一个列表,而在Python 3中,它返回一个生成器


您只能对其值进行迭代,否则可能需要显式地将其转换为列表,即将其传递给列表函数。

。或者仅仅是
list(d)
,它将在不复制任何副本的情况下为您提供python2.x和python3.x上的键列表:-)这是一个奇怪的突破性改变python3的设计决策。您可能会这样认为,但我肯定认为这是正确的决策。
dict\u keys
对象的行为更像dict的一半。具体来说,它们支持O(1)成员资格测试(以及其他类似集合的方法,可以在该事实的基础上高效实现)。这些事情在列表中是不可能实现的,如果你想要一个dict键列表,你总是可以简单地执行
list(你的字典)
来获得它。这对我很有帮助,因为python3要求我们用list来包装字典。@Crt--
shuffle
是原始海报代码中函数的名称(抛出错误的函数)。查看代码,我认为它是从标准库中的
随机.shuffle
实现中复制/粘贴的:-)答案与一般知识相关,但与OP的要求无关。你说得对。他似乎想实现自己的随机化器。psah,也许他并不知道他可以使用内置的,但问题实际上似乎是关于类型错误。不过,我希望他切换并使用您的选项(除非是非常具体的)来遵循基本的干式和代码经济原则。似乎是一个python3错误OP不想只访问第一个项目或一次遍历项目,他们需要随机访问项目以洗牌。有了这些需求,将iterable转换为列表正是正确的方法。此外,您的第二个代码片段可以替换为键中的项:pass
的更清晰、更高效的