Python辞書からキーを削除する方法は?


回答:


2841

辞書にあるかどうかに関係なくキーを削除するには、次の2つの引数の形式を使用しますdict.pop()

my_dict.pop('key', None)

これは、辞書に存在するmy_dict[key]場合は戻りkeyNoneそれ以外の場合は戻ります。2番目のパラメーターが指定されておらず(つまりmy_dict.pop('key'))、key存在しない場合は、a KeyErrorが発生します。

存在が保証されているキーを削除するには、次のコマンドを使用することもできます

del my_dict['key']

これはKeyError、キーが辞書にない場合にを発生させます。


153
時々pop()over を使用する利点del:そのキーの値を返します。このようにして、1行のコードでdictからエントリを取得および削除できます。
kratenko 2013

7
質問では、値を維持する必要はありません。これは不必要な複雑さを追加するだけです。@zigg(下)からの答えははるかに良いです。
Salvatore Cosentino 2017年

10
@SalvatoreCosentino私はあなたの議論に従うことができません。この回答のコードは、他の回答のコードよりも複雑ですか?
Sven Marnach 2017年

33
@SalvatoreCosentinoいいえ、関数の戻り値を無視することはまったく非効率的ではありません。全く逆– キーが存在しない場合、このソリューションはtry/ exceptソリューションよりもはるかに高速です。どちらかが読みやすくなるかもしれませんが、問題ありません。どちらも慣用的なPythonなので、好きなものを選択してください。しかし、この回答がより複雑または非効率的であると主張しても、単に意味がありません。
Sven Marnach

5
@ user5359531わかりません。これはどのように問題ですか?Pythonの組み込み型のメソッドはどれもを返さselfないため、これが返された場合は、かなり意外です。
Sven Marnach

353

具体的には、「これを行う1行の方法はありますか?」

if 'key' in my_dict: del my_dict['key']

...まあ、あなたは尋ねました ;-)

ただし、からオブジェクトを削除するこの方法はアトミックでdictないことを考慮する必要があります。ステートメントの実行中にある可能性が'key'ありますが、が実行される前に削除される可能性があり、その場合はで失敗します。これを考えると、それを使用するかまたはに沿って何かをすることが最も安全でしょうmy_dictifdeldelKeyErrordict.pop

try:
    del my_dict['key']
except KeyError:
    pass

もちろん、これは間違いなくワンライナーではありませ


27
うん、popそれをこのように行うの一つの重要な利点があるが、間違いなく、より簡潔である:それはすぐにそれがやっているものをクリアしています。
zigg

4
try/except声明は、より高価です。例外の発生は遅いです。
Chris Barker

16
@ChrisBarkerキーが存在する場合tryは、わずかに高速ですが、存在しない場合tryは、かなり低速です。 popかなり一貫性がありますが、すべてよりも遅いですがtry、存在しないキーがあります。gist.github.com/zigg/6280653を参照してください。最終的には、キーが実際にディクショナリにあると予想する頻度、およびアトミック性が必要かどうか、そしてもちろん、時期尚早の最適化を行っているかどうか
によって異なり

9
明快さの価値を見逃してはいけないと思います。+1。
ファンカルロスコト2014年

2
try / exceptの費用に関しては、あなたも行くことができますif 'key' in mydict: #then del...。正しく解析するために、dictからキー/値を取り出す必要がありました。popは完璧なソリューションではありませんでした。
2015

153

正確に何をしているのかを理解するのに少し時間がかかりましたmy_dict.pop("key", None)。だから私は他のグーグル時間を節約するための答えとしてこれを追加します:

pop(key[, default])

キーが辞書にある場合は、削除してその値を返し、そうでない場合はdefaultを返しますデフォルト指定されておらず、キーが辞書にない場合は、a KeyErrorが発生します。

ドキュメンテーション


15
Pythonインタープリターでhelp(dict.pop)と入力するだけです。
David Mulder

13
help()とdir()は、何かが必要なときに友だちになることができます。
David Mulder

3
またはdict.pop?IPythonで。
エリックカプルン2014

51

del my_dict[key]my_dict.pop(key)キーが存在するときに辞書からキーを削除するよりもわずかに速い

>>> import timeit
>>> setup = "d = {i: i for i in range(100000)}"

>>> timeit.timeit("del d[3]", setup=setup, number=1)
1.79e-06
>>> timeit.timeit("d.pop(3)", setup=setup, number=1)
2.09e-06
>>> timeit.timeit("d2 = {key: val for key, val in d.items() if key != 3}", setup=setup, number=1)
0.00786

ただし、キーが存在しない場合if key in my_dict: del my_dict[key]は、よりもわずかに高速ですmy_dict.pop(key, None)。どちらも、少なくとも3倍以上あるdeltry/ except声明:

>>> timeit.timeit("if 'missing key' in d: del d['missing key']", setup=setup)
0.0229
>>> timeit.timeit("d.pop('missing key', None)", setup=setup)
0.0426
>>> try_except = """
... try:
...     del d['missing key']
... except KeyError:
...     pass
... """
>>> timeit.timeit(try_except, setup=setup)
0.133

1
このような迅速な操作のタイミングを測定することは、かなり愚かです。a popをに変更したので、コードはおそらくそれほど速くなりませんdel。辞書を作成すると、辞書から完全に削除されます。
ボリス

1
@Boris-これは一般的な練習として役立ちます。
デイジー

1
@daisy私が言っていることは、300ナノ秒速い演算ではなく、最も読みやすい構文を選択する必要があるということです(これは、文字通り上記の最初のタイミングセットdelとの違いpopです)
ボリス

また、これらの操作は非常に高速であるため、これらのタイミングは信頼できません。
ボリス

46

1行のコードで辞書から多くのキーを削除する必要がある場合、map()を使用することは非常に簡潔で、Pythonで読みやすいと思います。

myDict = {'a':1,'b':2,'c':3,'d':4}
map(myDict.pop, ['a','c']) # The list of keys to remove
>>> myDict
{'b': 2, 'd': 4}

そして、辞書にない値をポップするエラーをキャッチする必要がある場合は、次のようにmap()内でラムダを使用します。

map(lambda x: myDict.pop(x,None), ['a', 'c', 'e'])
[1, 3, None] # pop returns
>>> myDict
{'b': 2, 'd': 4}

またはではpython3、代わりにリスト内包表記を使用する必要があります。

[myDict.pop(x, None) for x in ['a', 'c', 'e']]

できます。また、myDictに「e」キーがなかったとしても、「e」はエラーを引き起こしませんでした。


42
これはPython 3では機能しません。これはmap、友人が怠惰でイテレータを返すようになったためです。map副作用のために使用することは、一般的に悪い習慣と考えられています。標準for ... inループの方が良いでしょう。詳細については、リストの代わりにビューとイテレータを参照してください。
Greg Krimer、2015年

5
かかわらず、味と練習スタイルの、リストの内包表記は、まだPY3に動作するはずです[myDict.pop(i, None) for i in ['a', 'c']]、彼らは一般的に代替提供として、map(とがfilter)。
Michael Ekoka

@MichaelEkoka副作用のためにリスト内包表記を使用すべきではありませんfor ... in。通常のループを使用してください。
ボリス

@ボリスあなたはおそらく正しいです。私の答えは、特にmap()副作用のために使用されるの使用に特に関係しています。Pythonで推奨代替がある私の意見ではまだかなり読みやすいとワンライナーとして認知的に光でリスト内包、(質問を参照してください)。副作用のためだけに使用すると、どちらの構成要素も実際には役に立たないリストになり、非効率になる可能性があります。python3のように、私は内蔵の安全かつエレガント例えば副産物コストのかかるずに、ジェネレータ式を反復処理できる機能を認識していませんよloop(d.pop(k) for k in ['a', 'b'])
Michael Ekoka

私がこれまでで最も支持されていた回答に、私が使用することのないハッキングが含まれているのは面白いです。リストの内包表記(オプション3)は、私の意見では、最も悪い方法ではありません。あれを使って。
Marc Maxmeister

20

あなたは使用することができ辞書理解を取り外し、そのキーを使用して新しい辞書を作成します:

>>> my_dict = {k: v for k, v in my_dict.items() if k != 'key'}

条件で削除できます。key存在しなくてもエラーは発生しません。



7

次のいくつかの方法で、Python辞書からキーを削除できます。

delキーワードの使用; それはあなたがしたのとほとんど同じアプローチです-

 myDict = {'one': 100, 'two': 200, 'three': 300 }
 print(myDict)  # {'one': 100, 'two': 200, 'three': 300}
 if myDict.get('one') : del myDict['one']
 print(myDict)  # {'two': 200, 'three': 300}

または

以下のようにすることができます:

ただし、このプロセスでは、実際には特定のキーを辞書から除外するのではなく、キーを辞書から削除しないことに注意してください。さらに、と同じ順序で並べられていない辞書を返すことがわかりました。myDict

myDict = {'one': 100, 'two': 200, 'three': 300, 'four': 400, 'five': 500}
{key:value for key, value in myDict.items() if key != 'one'}

シェルで実行すると、次のように実行されます{'five': 500, 'four': 400, 'three': 300, 'two': 200}-と同じ順序ではないことに注意してmyDictください。繰り返しますがmyDict、printを実行すると、このアプローチで辞書から除外したキーを含むすべてのキーが表示されます。ただし、次のステートメントを変数に割り当てることで、新しい辞書を作成できます。

var = {key:value for key, value in myDict.items() if key != 'one'}

これを印刷しようとすると、親の順序に従います。

print(var) # {'two': 200, 'three': 300, 'four': 400, 'five': 500}

または

pop()メソッドを使用します。

myDict = {'one': 100, 'two': 200, 'three': 300}
print(myDict)

if myDict.get('one') : myDict.pop('one')
print(myDict)  # {'two': 200, 'three': 300}

違いdelpopそれは、使用しているpop()方法を、私たちが実際に格納できるキーの値を必要に応じて、以下のように、:

myDict = {'one': 100, 'two': 200, 'three': 300}
if myDict.get('one') : var = myDict.pop('one')
print(myDict) # {'two': 200, 'three': 300}
print(var)    # 100

これが便利だと思ったら、将来の参考のためにこの要点をフォークしください。


1
if myDict.get('one')キーが存在するかどうかを確認するために使用しないでください!myDict ['one']に誤った値があると失敗します。また、dictには固有の順序がないため、それを言及しても意味がありません。
ロブ

@Rob dictは、CPython 3.6から始まる挿入順、および3.7から始まる他のすべてのPython実装順に並べられています。
ボリス

4

非常に冗長にしたい場合は、例外処理を使用できます。

try: 
    del dict[key]

except KeyError: pass

ただし、pop()キーが存在しない場合は、メソッドよりも時間がかかります。

my_dict.pop('key', None)

いくつかのキーでは問題になりませんが、これを繰り返し行う場合は、後者の方法の方が適しています。

最速のアプローチはこれです:

if 'key' in dict: 
    del myDict['key']

しかし、このメソッドは'key'2つの行の間で削除されるとa KeyErrorが発生するので危険です。


1

不変バージョンを好む

foo = {
    1:1,
    2:2,
    3:3
}
removeKeys = [1,2]
def woKeys(dct, keyIter):
    return {
        k:v
        for k,v in dct.items() if k not in keyIter
    }

>>> print(woKeys(foo, removeKeys))
{3: 3}
>>> print(foo)
{1: 1, 2: 2, 3: 3}

1

別の方法は、items()+ dict内包表記を使用することです

dict内包と組み合わせたitems()は、キーと値のペアの削除というタスクの達成にも役立ちますが、インプレースのdict手法ではないという欠点があります。作成したくないキーを除いて、実際には新しいdictが作成されます。

test_dict = {"sai" : 22, "kiran" : 21, "vinod" : 21, "sangam" : 21} 

# Printing dictionary before removal 
print ("dictionary before performing remove is : " + str(test_dict)) 

# Using items() + dict comprehension to remove a dict. pair 
# removes  vinod
new_dict = {key:val for key, val in test_dict.items() if key != 'vinod'} 

# Printing dictionary after removal 
print ("dictionary after remove is : " + str(new_dict)) 

出力:

dictionary before performing remove is : {'sai': 22, 'kiran': 21, 'vinod': 21, 'sangam': 21}
dictionary after remove is : {'sai': 22, 'kiran': 21, 'sangam': 21}

0

キーの単一フィルター

  • 「key」を返し、「key」がmy_dictに存在する場合は、それをmy_dictから削除します
  • my_dictに「キー」が存在しない場合はNoneを返します

これはmy_dict場所によって変わります(可変)

my_dict.pop('key', None)

キーの複数のフィルター

新しい辞書を生成します(不変)

dic1 = {
    "x":1,
    "y": 2,
    "z": 3
}

def func1(item):
    return  item[0]!= "x" and item[0] != "y"

print(
    dict(
        filter(
            lambda item: item[0] != "x" and item[0] != "y", 
            dic1.items()
            )
    )
)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.