web-dev-qa-db-ja.com

Python3のインデックスによるdict_keys要素へのアクセス

私はそのインデックスによってdict_keyの要素にアクセスしようとしています:

test = {'foo': 'bar', 'hello': 'world'}
keys = test.keys()  # dict_keys object

keys.index(0)
AttributeError: 'dict_keys' object has no attribute 'index'

fooを取得したい。

と同じ:

keys[0]
TypeError: 'dict_keys' object does not support indexing

これどうやってするの?

98
fj123x

代わりに辞書でlist()を呼び出します:

keys = list(test)

Python 3では、dict.keys()メソッドは 辞書ビューオブジェクト を返します。これはセットとして機能します。辞書を直接反復処理するとキーも生成されるため、辞書をリストに変換すると、すべてのキーのリストが作成されます。

>>> test = {'foo': 'bar', 'hello': 'world'}
>>> list(test)
['foo', 'hello']
>>> list(test)[0]
'foo'
115
Martijn Pieters

完全な答えではなく、おそらく役立つヒントです。それが本当にあなたが欲しい最初のアイテムである場合*、

next(iter(q))

よりもはるかに高速です

list(q)[0]

大規模な辞書の場合、すべてをメモリに保存する必要はありません。

10.000.000アイテムの場合、ほぼ40.000倍高速であることがわかりました。

* dictが Python 3.6 の前の単なる擬似ランダム項目である場合の最初の項目(その後、標準実装で順序付けされますが、それに依存することはお勧めしません)。

45
Mark

多くの場合、これは XY問題 である可能性があります。辞書キーを位置でインデックス付けするのはなぜですか?本当に必要ですか?最近まで、辞書はPythonでも順序付けられていなかったため、最初の要素へのアクセスは任意でした。

いくつかのPython 2コードをPython 3に変換しました:

keys = d.keys()
for (i, res) in enumerate(some_list):
    k = keys[i]
    # ...

きれいではありませんが、それほど悪くもありません。最初は、怪物に置き換えようとしていました

    k = next(itertools.islice(iter(keys), i, None))

私がこれを理解する前に

for (k, res) in Zip(d.keys(), some_list):

うまく動作します。

他の多くの場合、辞書キーの位置によるインデックス付けは回避できると考えています。辞書はPython 3.7で順序付けられていますが、それに依存することは適切ではありません。上記のコードは、some_listのコンテンツがdのコンテンツから最近生成されたためにのみ機能します。

インデックスによってdisk_keys要素に本当にアクセスする必要がある場合は、コードをよく見てください。おそらくあなたはする必要はありません。

0
gerrit
test = {'foo': 'bar', 'hello': 'world'}
ls = []
for key in test.keys():
    ls.append(key)
print(ls[0])

静的に定義されたリストにキーを追加し、同じキーをインデックス付けする従来の方法

0
pranav dua