辞書キーが利用できない場合はNoneを返します


489

そのキーが存在する場合にディクショナリ値を取得する方法、または単に返す方法が必要です Noneしない場合はです。

ただし、KeyError存在しないキーを検索すると、Pythonでは例外が発生します。キーを確認できることはわかっていますが、もっと明確なものを探しています。Noneキーが存在しない場合に戻る方法はありますか?


74
.get(key)代わりに使用してください[key]
Gabe

12
dictはKeyError例外を発生させます。「key_errorを返す」ことはありません。
2010年

3
Pythonでは、キーにアクセスして例外をキャッチすることは完全に問題ありません。それはよく知られており、よく使用されるデザインパターンです。代わりにNoneを返すと、Noneを値として格納できなくなり、場合によっては関連する場合があります。
2010年

1
辞書の "なし"エントリと欠落しているエントリを同じように扱いたい場合があります。その場合、受け入れられた回答がうまく機能するようです。
cib 2015

@Ber明確にするために質問を編集しました。あなたもそうすることができたでしょう。
törzsmókus

回答:


813

使用できます dict.get()

value = d.get(key)

None場合は戻りますkey is not in d。次の代わりに返される別のデフォルト値を指定することもできますNone

value = d.get(key, "empty")

47
デフォルトのフォールバックを備えた2番目のバリアントNoneは、キーがNonedictで明示的にマッピングされている場合に返されることに注意してください。それが目的に合わない場合は、などを使用できますd.get(key) or "empty"
cib 2015

15
@cib:良い点、しかし、解決策は、同様の問題がある- (のようなキーは任意の「falsy」の値にマッピングされている場合は[]""False0.0実際またはNone)、その後、あなたのソリューションは、常に返します0None値としてs を期待する場合は、if key in d:明示的にチェックを行う必要があります。
Tim Pietzcker、2015

1
@cibはそれを応援します、私はここで間違っていることを理解することができませんでした。
wobbily_col

@TimPietzcker-あなたの答えを説明できますか?d.get(key)または「空」は、キーが「偽」の値にマップされている場合、誤っていない場合は「空」です。
MiloMinderbinder

@MiloMinderbinder:"empty"keyの有効なキーでない場合に返されdます。keyマッピング先の値とは関係ありません。
Tim Pietzcker

63

もう不思議ではありません。言語に組み込まれています。

    >>>ヘルプ(dict)

    組み込みモジュールのクラスdictに関するヘルプ:

    クラスdict(オブジェクト)
     | dict()->新しい空の辞書
     | dict(mapping)->マッピングオブジェクトから初期化された新しい辞書
     | (キー、値)ペア
    ...
     |  
     | 取得する(...)
     | D.get(k [、d])-> D [k](kがDの場合)、それ以外の場合はd。dのデフォルトはNoneです。
     |  
    ...

22

使用する dict.get

keyがディクショナリにある場合はkeyの値を返し、そうでない場合はデフォルトです。defaultが指定されていない場合、デフォルトはNoneなので、このメソッドはKeyErrorを発生させません。


19

クラスのget()メソッドを使用する必要がありますdict

d = {}
r = d.get('missing_key', None)

これはになりr == Noneます。キーが辞書にない場合、get関数は2番目の引数を返します。


19
None明示的に渡す必要はありません。これがデフォルトです。
ビョルンポレックス

18

より透過的なソリューションが必要な場合は、サブクラス化dictしてこの動作を実現できます。

class NoneDict(dict):
    def __getitem__(self, key):
        return dict.get(self, key)

>>> foo = NoneDict([(1,"asdf"), (2,"qwerty")])
>>> foo[1]
'asdf'
>>> foo[2]
'qwerty'
>>> foo[3] is None
True

2
@marineau:別の回答へのコメントで述べたように、問題は、defaultdictまだ存在しない要素が要求されるたびに大きくなることです。これは常に望ましいとは限りません。
ビョルンポレックス2011年

@BjörnPollexこれは非常にエレガントなものです。これを拡張して深さをサポートする方法についての手がかりはありますか?例外の代わりfoo['bar']['test']['sss']に戻るNoneようにすることを意味します。1つの深さの後、TypeError代わりに与え始めますKeyError
nehem

@itsneo。の構造全体を構築できNoneDictsます。これはKeyError、最も内側のオブジェクトで発生する場合に役立ちます。それ以外の場合の問題は、Noneオブジェクトを返すと、それをサブスクライブできなくなることです。醜いハックの1つは、のようにテストする別のオブジェクトを返すことNoneです。ただし、これは恐ろしいバグにつながる可能性があることに注意してください。
magu_

@BjörnPollexに変更return dict.get(self, key)してもよろしいreturn super().get(key)ですか?たとえば、dictの代わりにOrderedDictを使用する場合、複数行のコードを変更する必要はありません。
ウッド

@ウッドはい、それは実際にははるかに良いでしょう!
ビョルンPollex

12

私は通常、このような状況ではdefaultdictを使用します。引数を取らず、新しいキーを検出したときに値を作成するファクトリメソッドを提供します。新しいキーで空のリストのようなものを返したい場合に便利です(例を参照)。

from collections import defaultdict
d = defaultdict(lambda: None)
print d['new_key']  # prints 'None'

19
の問題は、defaultdict存在しない要素が要求されるたびに成長し続けることです。
ビョルンポレックス

8

他の人がすでに提案しているように、dictオブジェクトのget()メソッドを使用できます。あるいは、何をしているかに応じて、次のtry/exceptようなスイートを使用できる場合があります。

try:
   <to do something with d[key]>
except KeyError:
   <deal with it not being there>

これは、ケースを処理するための非常に「Python的な」アプローチであると考えられています。


7

1行のソリューションは次のようになります。

item['key'] if 'key' in item else None

これは、ディクショナリ値を新しいリストに追加しようとして、デフォルトを提供したい場合に役立ちます。

例えば。

row = [item['key'] if 'key' in item else 'default_value']

5

他の人が上で言ったように、あなたはget()を使うことができます。

ただし、キーを確認するには、次の操作も実行できます。

d = {}
if 'keyname' in d:

    # d['keyname'] exists
    pass

else:

    # d['keyname'] does not exist
    pass

私は、あなたがすでにこれを行う方法を知っていることを理解しました。私は自分の投稿を削除するつもりでしたが、他の人が参照できるように残しておきます。
Marek P、

4
このアプローチでは、通常、キーが存在するときにキーを2回検索する必要があります。これが、おそらくgetメソッドの理由です。
martineau

0

私はpython2とpython3で可能だったことにびっくりしました。python3の結果に基づいて答えます。私の目的は単純でした:辞書形式のjson応答でエラーが発生したかどうかを確認してください。私の辞書は「トークン」と呼ばれ、私が探しているキーは「エラー」です。私はキー「エラー」を探していますが、そこに値Noneを設定していない場合は、値がNoneであるかどうかを確認します。そうであれば、コードを続行します。「エラー」キーがある場合は、elseステートメントで処理します。

if ((token.get('error', None)) is None):
    do something

-2

でそれを行うことができる場合はFalsehasattr組み込み関数もあります。

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