web-dev-qa-db-ja.com

Pythonで辞書のキーをリストとして返すにはどうすればいいですか?

Python 2.7 では、辞書キー values 、またはを取得できますリストとしての/] items

>>> newdict = {1:0, 2:0, 3:0}
>>> newdict.keys()
[1, 2, 3]

さて、 Python> = 3.3 では、次のようになります。

>>> newdict.keys()
dict_keys([1, 2, 3])

それで、私はリストを得るためにこれをしなければなりません:

newlist = list()
for i in newdict.keys():
    newlist.append(i)

私が思っているのは、 Python 3 でリストを返すためのより良い方法はありますか?

524
user2015601

list(newdict.keys())を試してください。

これはdict_keysオブジェクトをリストに変換します。

その一方で、あなたはそれが重要であるかどうか自分自身に尋ねるべきです。 Pythonicでコーディングする方法は、アヒルのタイプを仮定することです(それがアヒルのように見えて、それがアヒルのようにぎくしゃくしている場合、それはアヒルです)。 dict_keysオブジェクトはほとんどの目的のためにリストのように振る舞います。例えば:

for key in newdict.keys():
  print(key)

明らかに、挿入演算子は機能しないかもしれませんが、それでも辞書キーのリストにはあまり意味がありません。

670
Chris

Python> = 3.5選択肢:リストリテラルに展開する[*newdict]

Python 3.5で新しい 開梱一般化(PEP 448) が導入され、簡単にできるようになりました。

>>> newdict = {1:0, 2:0, 3:0}
>>> [*newdict]
[1, 2, 3]

*によるアンパックは反復可能な任意のオブジェクトで機能します。また、辞書を反復処理するとキーが返されるため、リストリテラル内で使用することでリストを簡単に作成できます。

.keys()、すなわち[*newdict.keys()]を追加することはあなたの意図をもう少し明確にするのに役立つかもしれません、しかしそれはあなたに関数の検索と呼び出しを犠牲にするでしょう。 (正直言って、本当にを気にするべきではありません)。

*iterable構文はlist(iterable)を実行するのに似ていて、その振る舞いはPythonリファレンスマニュアルの Callsセクション で最初に文書化されました。 PEP 448では、*iterableが現れる場所の制限が緩和され、list、set、Tupleリテラルにも置くことができました。 式リストに関するリファレンスマニュアル これを述べるためにまた更新されました。


list(newdict)と同等ですが、実際には関数呼び出しが実行されないため、(少なくとも小さい辞書では)高速です。

%timeit [*newdict]
1000000 loops, best of 3: 249 ns per loop

%timeit list(newdict)
1000000 loops, best of 3: 508 ns per loop

%timeit [k for k in newdict]
1000000 loops, best of 3: 574 ns per loop

より大きな辞書では、速度はほとんど同じです(大きなコレクションを繰り返すことによるオーバーヘッドは、関数呼び出しの小さなコストを上回ります)。


同様の方法で、タプルと辞書キーのセットを作成できます。

>>> *newdict,
(1, 2, 3)
>>> {*newdict}
{1, 2, 3}

タプルの場合は末尾のカンマに注意してください。

170

list(newdict)はPython 2とPython 3の両方で動作し、newdictのキーの簡単なリストを提供します。 keys()は必要ありません。 (:

26
Seb

「ダックタイピング」の定義を少しオフにした場合 - dict.keys()は、リストのようなオブジェクトではなく、反復可能なオブジェクトを返します。これは、イテラブルが機能する場所ならどこでも機能します - リストが機能する場所ではありません。リストも繰り返し可能ですが、繰り返し可能はリスト(またはシーケンス...)ではありません

実際のユースケースでは、辞書内のキーを使用して行う最も一般的なことはそれらを反復処理することですので、これは理にかなっています。そしてそれらがリストとして必要な場合はlist()を呼びます。

Zip()の場合と非常によく似ています - ほとんどの場合、それは繰り返し実行されます - 繰り返し実行するためにまったく新しいタプルのリストを作成し、それを再び捨てるのはなぜでしょうか。

これは、至るところにあるリストのコピーではなく、より多くのイテレーター(およびジェネレーター)を使用するというPythonの大きな傾向の一部です。

dict.keys()は内包表記で動作するはずです - タイプミスか何かを慎重にチェックしてください...それは私にとってはうまくいきます:

>>> d = dict(Zip(['Sounder V Depth, F', 'Vessel Latitude, Degrees-Minutes'], [None, None]))
>>> [key.split(", ") for key in d.keys()]
[['Sounder V Depth', 'F'], ['Vessel Latitude', 'Degrees-Minutes']]
23
Chris Barker

リスト内包表記を使うこともできます。

>>> newdict = {1:0, 2:0, 3:0}
>>> [k  for  k in  newdict.keys()]
[1, 2, 3]

または、もっと短い、

>>> [k  for  k in  newdict]
[1, 2, 3]

注:順序は3.7未満のバージョンでは保証されていません(順序はCPython 3.6の実装の詳細にすぎません)。

keysメソッドを使用せずにリストに変換すると、読みやすくなります。

list(newdict)

そして、辞書をループするとき、keys()の必要はありません:

for key in newdict:
    print key

ループ内で変更しているのでない限り、事前に作成されたキーのリストが必要になります。

for key in list(newdict):
    del newdict[key]

Python 2では、 keys()を使用すると、パフォーマンスがわずかに向上します。

8
Cas

キーを別々に保存する必要がある場合は、 Extended Iterable Unpacking (python3.x +)を使用して、これまでに提示した他のすべてのソリューションよりも入力が少なくて済むソリューションです。 ).

newdict = {1: 0, 2: 0, 3: 0}
*k, = newdict

k
# [1, 2, 3]

            ╒═══════════════╤═════════════════════════════════════════╕
            │ k = list(d)   │   9 characters (excluding whitespace)   │
            ├───────────────┼─────────────────────────────────────────┤
            │ k = [*d]      │   6 characters                          │
            ├───────────────┼─────────────────────────────────────────┤
            │ *k, = d       │   5 characters                          │
            ╘═══════════════╧═════════════════════════════════════════╛
6
cs95

Tuple(dict)またはset(dict)を実行することもできます。

>>> list(set(newdict))
[1, 2, 3]
>>> list(Tuple(newdict))
[1, 2, 3]
2
SuperNova
list(newdict)

これは最も簡単なソリューションであり、魅力のように機能しました!

2
Muhammad Haseeb

このページに記載されている方法以外に、オペレータモジュールからitemgetterを使用することもできます。

>>> from operator import itemgetter
>>> list(map(itemgetter(0), dd.items()))
[1, 2, 3]
1
SuperNova

リスト(newdict.keys())

list(newdict.keys())
0
Sat110