web-dev-qa-db-ja.com

Python dictionary.keys()エラー

私は.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']を印刷するだけです。

どうしたの?

42
tokageKitayama

Python 3はdict.keysの動作を変更し、反復可能ながインデックス化できないdict_keysオブジェクトを返すようになりました(古いdict.iterkeysは廃止されました)。 listを明示的に呼び出すと、Python 2の結果が返されます。

>>> b = { 'video':0, 'music':23 }
>>> k = list(b.keys())
>>> k
['music', 'video']

あるいは単に

>>> list(b)
['music', 'video']
91
Fred Foo

kを次のように割り当てた場合:

k = list(b.keys())

コードが機能します。

エラーが言うように、dict_keysタイプはインデックス作成をサポートしていません。

8
NPE

これは、Python 2と3の間の重大な変更の1つです。

In Python 2:

_>>> help(dict.keys)
keys(...)
    D.keys() -> list of D's keys
_

In Python 3:

_>>> help(dict.keys)
keys(...)
    D.keys() -> a set-like object providing a view on D's keys
_

Dictは意味的に順序付けられておらず、そのキーはセットのように一意であるため、この動作の変更は非常に理にかなっています。

この変更により、dictのキーと何らかのセット比較を行うたびにキーの新しいリストを作成する必要がなくなります。

2と3で同じ動作をする

Python 3、Python 2.7には別のdictメソッド、viewkeysがあります。viewkeysメソッドは最も類似しています。 to 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']
_

または、dictがlistに渡されるだけです。これは、dictがキーを繰り返し処理するためです。

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

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にdictを渡すと、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']
_
2
Aaron Hall

辞書のキーのリストが必要な場合は、次のように直接実行できます。

b = {"name": "xyz", "class":"abc", "college": "qwert"}  
key_list = list(b)

key_listにはすべてのキー名がリストとして含まれますが、複数回見つかった場合、キーは繰り返されません。重複キーは1つとしてカウントされます。

0
vikas0713