web-dev-qa-db-fra.com

TypeError: l'objet 'dict_keys' ne supporte pas l'indexation

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]

Lorsque j'exécute la fonction shuffle, l'erreur suivante est générée. Pourquoi?

TypeError: 'dict_keys' object does not support indexing
104
gate_007

Clairement, vous passez de d.keys() à votre fonction shuffle. Cela a probablement été écrit avec python2.x (lorsque d.keys() a renvoyé une liste). Avec python3.x, d.keys() renvoie un objet dict_keys qui se comporte beaucoup plus comme un set qu'un list. En tant que tel, il ne peut pas être indexé.

La solution consiste à passer list(d.keys()) (ou simplement list(d)) à shuffle.

181
mgilson

Vous passez le résultat de somedict.keys() à la fonction. En Python 3, dict.keys ne renvoie pas de liste, mais un objet semblable à un ensemble qui représente une vue des clés du dictionnaire et (qui ressemble à un ensemble) ne supporte pas l'indexation.

Pour résoudre le problème, utilisez list(somedict.keys()) pour collecter les clés et travaillez avec cela.

9
user4815162342

Convertir un itérable en une liste peut avoir un coût. Pour obtenir le premier élément, vous pouvez utiliser:

next(iter(keys))

Ou, si vous souhaitez parcourir tous les éléments, vous pouvez utiliser:

items = iter(keys)
while True:
    try:
        item = next(items)
    except StopIteration as e:
        pass # finish
5
sahama

En Python 2, dict.keys () renvoie une liste, alors qu'en Python 3, il renvoie un générateur.

Vous pouvez uniquement parcourir ses valeurs, sinon vous devrez peut-être explicitement le convertir en liste, par exemple en le passant à une fonction de liste.

2
DeWil

Pourquoi devez-vous mettre en œuvre le mélange lorsque celui-ci existe déjà? Restez sur les épaules des géants.

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)
0
foo bar