web-dev-qa-db-ja.com

TypeError: 'dict_keys'オブジェクトはインデックス作成をサポートしていません

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
126
gate_007

明らかに、d.keys()shuffle関数に渡しています。おそらくこれはpython2.xで書かれたものです(d.keys()がリストを返したとき)。 python3.xでは、d.keys()dict_keysオブジェクトを返します。このオブジェクトは、setよりもlistのように動作します。そのため、インデックスを作成できません。

解決策は、list(d.keys())(または単にlist(d))をshuffleに渡すことです。

207
mgilson

somedict.keys()の結果を関数に渡します。 Python 3では、dict.keysはリストを返しませんが、辞書のキーのビューを表す(セットのような)セットのようなオブジェクトはインデックス作成をサポートしません。

問題を修正するには、list(somedict.keys())を使用してキーを収集し、それを操作します。

10
user4815162342

反復可能オブジェクトをリストに変換するには、コストがかかる場合があります。代わりに、最初のアイテムを取得するには、次を使用できます。

next(iter(keys))

または、すべてのアイテムを反復処理する場合は、次を使用できます。

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

Python 2ではdict.keys()はリストを返しますが、Python 3ではジェネレーターを返します。

値だけを反復処理することができます。それ以外の場合は、明示的にリストに変換する必要があります。つまり、リスト関数に渡します。

2
DeWil

シャッフルが既に存在するのに、なぜシャッフルを実装する必要があるのですか?巨人の肩にとどまる。

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