なぜdict [key]ではなくdict.get(key)なのですか?


651

今日、私は、辞書のキーを指定して、関連する値を返すdictメソッドに出会いましたget

この機能はどのような目的で役立ちますか?辞書でキーに関連付けられた値を検索したい場合は、を実行するだけでdict[key]同じことが返されます。

dictionary = {"Name": "Harry", "Age": 17}
dictionary["Name"]
dictionary.get("Name")

1
dictionary["foo"]dictionary.get("foo")ただし、動作は異なります。
Niklas B.

34
dictionary.get("Age") 書き込みと同じなdictionary["Age"] or None ので、暗黙的にKeyError例外を処理します
yosemite_k

5
@yosemite_kここで一部のコンテキストが欠落している可能性がありますが、dictionary['non-existent key'] or Noneそれでもまだ発生KeyErrorします(v3.6まで)。どういう意味ですか?
nivk 2018

@nivk dictionary ['non-existent key']はエラーを発生させ、そのエラーは明示的に処理する必要があります。代わりに、dictionary.get()を使用すると(文字通り、dictionary ['non-existent key']またはNoneとして機能します)、その例外は暗黙的に処理されます。
yosemite_k

回答:


992

キーがない場合は、デフォルト値を指定できます。

dictionary.get("bogus", default_value)

default_value(あなたがそれを選択したものは何でも)を返しますが、

dictionary["bogus"]

を上げるだろうKeyError

省略した場合default_valueNone

dictionary.get("bogus")  # <-- No default specified -- defaults to None

Noneように戻ります

dictionary.get("bogus", None)

だろう。


1
これは同じdictionary.get("bogus") or my_defaultですか?私は人々がそれをいくつかのケースで使用するのを見てきました、そして、他のものの代わりに1つを使用することの利点(読みやすさ以外に)があるかどうか疑問に思いました
アルゴリズム

15
@MustafaS:場合は"bogus"内鍵であるdictionarydictionary.get("bogus")、このような0または空の文字列として、ブール値コンテキスト(すなわちA Falsey値)における偽に評価値を返し''、その後dictionary.get("bogus") or my_defaultに評価されるであろうmy_default一方dictionary.get("bogus", my_default)Falsey値を返します。したがって、dictionary.get("bogus") or my_defaultと同等ではありませんdictionary.get("bogus", my_default)。どちらを使用するかは、希望する動作によって異なります。
unutbu

3
@MustafaS:たとえば、と仮定しますx = {'a':0}。次にx.get('a', 'foo')戻ります0が、をx.get('a') or 'foo'返します'foo'
unutbu

3
使用時の1つの注意点dictionary.get('key'):辞書の値が混乱している可能性がありNoneます。戻り値(2番目のオプションの引数)を指定しないと、キーが存在しないかどうか、またはその値がかどうかを確認する方法はありませんNone。この特定のケースでは、の使用を検討しtry-except-KeyErrorます。
Aart Goossens 2016

1
デフォルト値を指定する式は「get」呼び出しで評価されるため、アクセスごとに評価されることに注意してください。(KeyErrorハンドラーまたは述語のいずれかを使用する)古典的な代替方法は、キーがない場合にのみデフォルト値を評価することです。これにより、クロージャー/ラムダを一度作成して、欠落しているキーを評価することができます。
トムスタンボー2018

142

dict.get()方法は何ですか?

すでに述べたように、getメソッドには欠損値を示す追加のパラメーターが含まれています。ドキュメントから

get(key[, default])

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

例は

>>> d = {1:2,2:3}
>>> d[1]
2
>>> d.get(1)
2
>>> d.get(3)
>>> repr(d.get(3))
'None'
>>> d.get(3,1)
1

速度の改善はどこにありますか?

ここで述べたよう

3つのアプローチすべてが、類似したパフォーマンスを示しているようです(互いに約10%以内)。これは、単語リストのプロパティとは無関係です。

以前getはかなり低速でしたが、現在は速度がほぼ同等で、デフォルト値に戻るという追加の利点があります。しかし、すべてのクエリをクリアするために、かなり大きなリストでテストすることができます(テストにはすべての有効なキーのみの検索が含まれることに注意してください)

def getway(d):
    for i in range(100):
        s = d.get(i)

def lookup(d):
    for i in range(100):
        s = d[i]

次に、これら2つの関数のタイミングを timeit

>>> import timeit
>>> print(timeit.timeit("getway({i:i for i in range(100)})","from __main__ import getway"))
20.2124660015
>>> print(timeit.timeit("lookup({i:i for i in range(100)})","from __main__ import lookup"))
16.16223979

関数のルックアップがないため、ルックアップはgetよりも高速です。これは、dis

>>> def lookup(d,val):
...     return d[val]
... 
>>> def getway(d,val):
...     return d.get(val)
... 
>>> dis.dis(getway)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_ATTR                0 (get)
              6 LOAD_FAST                1 (val)
              9 CALL_FUNCTION            1
             12 RETURN_VALUE        
>>> dis.dis(lookup)
  2           0 LOAD_FAST                0 (d)
              3 LOAD_FAST                1 (val)
              6 BINARY_SUBSCR       
              7 RETURN_VALUE  

それはどこで役に立ちますか?

辞書を検索しているときはいつでも、デフォルト値を提供したいときに役立ちます。これにより、

 if key in dic:
      val = dic[key]
 else:
      val = def_val

1行に val = dic.get(key,def_val)

役に立たない場所はどこですか?

KeyError特定のキーが使用できないことを示すメッセージを返したい場合。デフォルト値を返すことには、特定のデフォルト値も重要になる可能性があるというリスクがあります。

getような機能を持つことは可能dict['key']ですか?

はい!__missing__dictサブクラスでを実装する必要があります。

サンプルプログラムは

class MyDict(dict):
    def __missing__(self, key):
        return None

小さなデモは

>>> my_d = MyDict({1:2,2:3})
>>> my_d[1]
2
>>> my_d[3]
>>> repr(my_d[3])
'None'

32
StackOverflowのゴールドスタンダードが答えます!
アポロデータ


1
もう1つの良いテストはif k in dict and dict[k]:vs if dict.get(k):です。これは、キーが存在するかどうかを確認する必要がある状況と、「はい」の場合-どのような値ですか?のようなものですdict = {1: '', 2: 'some value'}
TitanFighter 2017

7
デフォルト値は関係なく、辞書にある値の評価を取得し、その代わりにすることを覚えておいてください dictionary.get(value, long_function())1が使用して検討するかもしれないdictionary.get(value) or long_function()
Kresimir

ああ@Kresimir、本当。私が直面したインタビューの1つでその質問を受けました(私が最初にこの回答を投稿したときは知りませんでした)。それについて思い出させてくれてありがとう。
Bhargav Rao

32

get2番目のオプションの値を取ります。指定したキーが辞書に存在しない場合、この値が返されます。

dictionary = {"Name": "Harry", "Age": 17}
dictionary.get('Year', 'No available data')
>> 'No available data'

2番目のパラメーターを指定しない場合は、Noneが返されます。

のようにインデックスを使用するとdictionary['Year']、存在しないキーが発生しKeyErrorます。


19

Pythonを使用してWebデータをスクレイピングする実用的な例を示します。多くの場合、値のないキーを取得します。これらの場合、dictionary ['key']を使用するとエラーが発生しますが、dictionary.get( 'key '、' return_otherwise ')は問題ありません。

同様に、リストから単一の値を取得する場合は、list [0]ではなく '' .join(list)を使用します。

それが役に立てば幸い。

[編集]これは実際的な例です:

たとえば、APIを呼び出して、解析する必要があるJOSNファイルを返すとします。最初のJSONは次のようになります。

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","submitdate_ts":1318794805,"users_id":"2674360","project_id":"1250499"}}

2番目のJOSNは次のようになります。

{"bids":{"id":16210506,"submitdate":"2011-10-16 15:53:25","submitdate_f":"10\/16\/2011 at 21:53 CEST","submitdate_f2":"p\u0159ed 2 lety","users_id":"2674360","project_id":"1250499"}}

2番目のJSONには「submitdate_ts」キーがないことに注意してください。これは、どのデータ構造でもかなり正常です。

したがって、ループ内でそのキーの値にアクセスしようとすると、次のように呼び出すことができます。

for item in API_call:
    submitdate_ts = item["bids"]["submitdate_ts"]

可能ですが、キーが存在しないため、2行目のJSON行のトレースバックエラーが発生します。

これをコーディングする適切な方法は、次のとおりです。

for item in API_call:
    submitdate_ts = item.get("bids", {'x': None}).get("submitdate_ts")

{'x':None}は、第2レベルでエラーが発生するのを防ぐためにあります。もちろん、スクレイピングを行っている場合は、コードにフォールトトレランスを組み込むことができます。最初にif条件を指定するように


2
あなたには、いくつかのコード例を掲載していた場合(けれども、私から+1)を、より多くのupvoted、おそらく受け入れされていたであろう他の任意の前に掲示良い答え、
Mawgはモニカ回復言う

2
@Mawg私は最近、私の研究のためにスクレイピングプロジェクトを行っていました。基本的にはAPIを呼び出してJSONファイルを解析していました。RAにやってもらいました。彼が抱えていた重要な問題の1つは、キーを直接呼び出すことでした。上記のテキストに例を掲載します。
ケビン

この多次元的な側面に取り組んでくれてありがとう!{'x':None}の代わりに{}を実行することもできるように
聞こえ

17

目的は、キーが見つからない場合にデフォルト値を指定できることです。これは非常に便利です。

dictionary.get("Name",'harry')

8

この機能はどのような目的で役立ちますか?

1つの特定の使用法は、ディクショナリで数えることです。与えられたリストの各要素の出現回数を数えたいとしましょう。これを行う一般的な方法は、キーが要素で値が出現回数である辞書を作成することです。

fruits = ['apple', 'banana', 'peach', 'apple', 'pear']
d = {}
for fruit in fruits:
    if fruit not in d:
        d[fruit] = 0
    d[fruit] += 1

.get()メソッドを使用すると、このコードをよりコンパクトで明確にすることができます。

for fruit in fruits:
    d[fruit] = d.get(fruit, 0) + 1

7

を使用するときに注意すべき落とし穴.get()

ディクショナリにへの呼び出しで使用されるキーが含まれ、.get()その値がNoneである場合、デフォルト値が指定されていても.get()メソッドは戻りNoneます。

たとえば、次のコードNone'alt_value'期待どおりではないを返します。

d = {'key': None}
d.get('key', 'alt_value')

.get()の2番目の値は、指定されたキーが辞書にない場合にのみ返され、その呼び出しの戻り値がの場合は返されませんNone


1
これは私を手に入れました:\これを解決する1つの方法は、d.get('key') or 'alt_value'それがそうであるかもしれないとわかっているかどうかを知ることですNone
ダニエル・ホームズ

4

なぜdict [key]ではなくdict.get(key)なのですか?

0.まとめ

比較するとdict[key]dict.getキーを見上げフォールバック値を提供します。

1.定義

get(key [、default]) 4.組み込み型— Python 3.6.4rc1ドキュメント

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

d = {"Name": "Harry", "Age": 17}
In [4]: d['gender']
KeyError: 'gender'
In [5]: d.get('gender', 'Not specified, please add it')
Out[5]: 'Not specified, please add it'

2.解決する問題。

がなければdefault value、このような例外を処理するには面倒なコードを書く必要があります。

def get_harry_info(key):
    try:
        return "{}".format(d[key])
    except KeyError:
        return 'Not specified, please add it'
In [9]: get_harry_info('Name')
Out[9]: 'Harry'
In [10]: get_harry_info('Gender')
Out[10]: 'Not specified, please add it'

便利な解決策として、dict.getオプションのデフォルト値を導入して、不用意にコードを回避しています。

3.まとめ

dict.get 辞書にキーがない場合の例外を処理する追加のデフォルト値オプションがあります


0

利点となる可能性のある1つの違いは、存在しないキーを探していると、ブラケット表記を使用する場合とは異なり、Noneを取得することです。この場合、エラーがスローされます。

print(dictionary.get("address")) # None
print(dictionary["address"]) # throws KeyError: 'address'

getメソッドのクールな最後の点は、デフォルト値の追加のオプション引数を受け取ることです。つまり、生徒のスコア値を取得しようとしたが、生徒が取得できるスコアキーを持っていない場合です。代わりに0。

したがって、これを行う代わりに(または類似の何か):

score = None
try:
    score = dictionary["score"]
except KeyError:
    score = 0

できるよ:

score = dictionary.get("score", 0)
# score = 0

-1

使用法に基づいて、このgetメソッドを使用する必要があります。

例1

In [14]: user_dict = {'type': False}

In [15]: user_dict.get('type', '')

Out[15]: False

In [16]: user_dict.get('type') or ''

Out[16]: ''

例2

In [17]: user_dict = {'type': "lead"}

In [18]: user_dict.get('type') or ''

Out[18]: 'lead'

In [19]: user_dict.get('type', '')

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