Pythonで辞書キーをリストとして返す方法は?


782

Python 2.7、私は辞書得ることができるキー、またはアイテムリストなどを:

>>> 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でリストを返すより良い方法はありますか?


このトピックについての興味深いスレッドの安全性の問題はここにある:blog.labix.org/2008/06/27/...
ポール・

2
私はPythonを使い始めたばかりで、役に立たない新しいデータ型の急増はPythonの最悪の側面の1つであるように思えます。このdict_keysデータ型の用途は何ですか?なぜリストではないのですか?
Phil Goetz

回答:


977

お試しくださいlist(newdict.keys())

これにより、dict_keysオブジェクトがリストに変換されます。

一方、それが重要かどうかを自問する必要があります。Pythonでコーディングする方法は、アヒルのタイピングを想定することです(アヒルのように見えて、アヒルのように鳴る場合は、アヒルです)。dict_keysオブジェクトは、ほとんどの目的のために、リストのように動作します。例えば:

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

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


49
newdict.keys()はインデックス作成をサポートしていません
gypaetus

57
list(newdict)(少なくともpython 3.4でも)動作します。この.keys()方法を使用する理由はありますか?
naught101

46
注:pdb> list(newdict.keys()) 同じ名前のpdbのコマンドと競合するため、デバッガーでは失敗します。pdb> !list(newdict.keys())pdbコマンドをエスケープするために使用します。
Riaz Rizvi

24
@ naught101はい、.keys()何が起こっているかについてはより明確です。
Felix D.

2
list(newdict.keys())を使用する場合、ハッシュ順のため、キーが配置した順序になっていないことに注意してください!
Nate M

277

Python> = 3.5の代替:リストリテラルに解凍 [*newdict]

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

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

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

.keys()ieを追加する[*newdict.keys()]と、関数の検索と呼び出しにコストがかかりますが、意図をもう少し明確にするのに役立ちます。(正直なところ、これは本当に心配する必要あることではありません)。

*iterable構文はやってに似てlist(iterable)、その振る舞いは、最初に文書化されたコールのセクション Pythonリファレンスマニュアルの。PEP 448では、*iterable表示できる場所の制限が緩和され、リスト、セット、およびタプルリテラルにも配置できるようになりました。式リストのリファレンスマニュアルも更新され、これが記載されています。


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}

タプルの場合の末尾のコンマに注意してください!


偉大な説明が、あなたは、構文のこの「* newdict」タイプを記述する任意のリンクを参照することができますしてください、私は意味どのように、なぜちょうどunderstanding.Thanx用の辞書から、このリターンキー
ムハンマドYounus

1
構文はあなたが行うことができます関数呼び出しでも、Pythonの2に、かなりの時間のために利用されたことを@MYounas def foo(*args): print(args)が続くfoo(*{1:0, 2:0})結果に(1, 2)印刷されています。この動作は、リファレンスマニュアルの「呼び出し」セクションで指定されています。PEP 448を備えたPython 3.5は、これらが表示される場所の制限を緩和し、[*{1:0, 2:0}]現在使用できるようにしました。いずれにせよ、私は私の答えを編集してこれらを含めます。
Dimitris Fasarakis Hilliard 2018

1
*newdict-これは間違いなくコードゴルファーにとっての答えです。また、これは正直なところ、本当に心配する必要のあることではありません心配な場合は、pythonを使用しないください
ArtemisはまだSEを信頼していません

46

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


26

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

実際のユースケースでは、dictのキーを使用する最も一般的なことは、キーを反復処理することです。これは理にかなっています。そして、リストとしてそれらが必要な場合は、呼び出すことができます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']]

2
あなたも使用する必要はありません.keys()。辞書オブジェクトはそれ自体が反復可能であり、反復処理時にキーを生成します[key.split(", ") for key in d]
Martijn Pieters

25

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

>>> 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での実装の詳細のみです)。


6
だけを使用してくださいlist(newdict)。ここではリストを理解する必要はありません。
Martijn Pieters

8

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

list(newdict)

そして、辞書をループする場合、以下の必要はありませんkeys()

for key in newdict:
    print key

事前に作成されたキーのリストを必要とするループ内でそれを変更していない限り:

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

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


8

キーを個別に保存する必要がある場合は、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                          
            ╘═══════════════╧═════════════════════════════════════════╛

1
私が指摘する唯一のマイナーな警告は、それkが常にここにリストされていることです。ユーザーがタプルまたはキーからのセットを必要とする場合、他のオプションにフォールバックする必要があります。
Dimitris Fasarakis Hilliard

1
より多くの注目すべきノートが文として、事実である*k, = dことが表示されます(ただし、見て、おそらくのためにこの答えを更新することができる場所に制限があり、PEP 572 -拡張開梱は、ATM代入式ではサポートされませんが、それはいつかかもしれません! )
Dimitris Fasarakis Hilliard

リストにキーと値の両方が必要な場合はどうなりますか?
内部石

1
@endolith keys, vals = zip(*d.items())(おそらく2つのタプルを提供しますが、十分に近いものです)。これより短い表現は知りません。
cs95

1

辞書からキーを抽出する方法は2つ考えられます。

方法1:-. keys()メソッドを使用してキーを取得し、それをリストに変換します。

some_dict = {1: 'one', 2: 'two', 3: 'three'}
list_of_keys = list(some_dict.keys())
print(list_of_keys)
-->[1,2,3]

方法2:- 空のリストを作成し、ループを介してリストにキーを追加します。このループでも値を取得できます(キーのみの場合は.keys()を使用し、キーと値の抽出の両方に.items()を使用します)

list_of_keys = []
list_of_values = []
for key,val in some_dict.items():
    list_of_keys.append(key)
    list_of_values.append(val)

print(list_of_keys)
-->[1,2,3]

print(list_of_values)
-->['one','two','three']
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.