今日、私はdict
メソッドget
に遭遇しました。それは辞書のキーが与えられると、関連する値を返します。
この機能はどのような目的に役立ちますか?辞書でキーに関連付けられた値を見つけたい場合は、dict[key]
を実行するだけで、同じことが返されます。
dictionary = {"Name": "Harry", "Age": 17}
dictionary["Name"]
dictionary.get("Name")
キーがない場合はデフォルト値を入力できます。
dictionary.get("bogus", default_value)
default_value
を返します(あなたが選んだものはなんでも)、それに対して
dictionary["bogus"]
KeyError
を上げるでしょう。
省略した場合、default_value
はNone
になります。
dictionary.get("bogus") # <-- No default specified -- defaults to None
以下のようにNone
を返します。
dictionary.get("bogus", None)
だろう。
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]
timeit
を使用してこれら2つの関数のタイミングを調整
>>> 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 = key[dic]
else:
val = def_val
単一行に、val = dic.get(key,def_val)
どこで役に立ちませんか?
特定のキーが利用できないことを示すKeyError
を返したいときはいつでも。デフォルト値を返すと、特定のデフォルト値も重要になる可能性があります。
dict['key']
にget
のような機能を持たせることは可能ですか?
はい! __missing__
を辞書サブクラスに実装する必要があります。
サンプルプログラムは
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'
get
は、2番目のオプション値を取ります。指定されたキーがあなたの辞書に存在しない場合、この値が返されます。
dictionary = {"Name": "Harry", "Age": 17}
dictionary.get('Year', 'No available data')
>> 'No available data'
2番目のパラメータを指定しないと、None
が返されます。
dictionary['Year']
のようにインデックスを使用すると、存在しないキーはKeyError
を発生させます。
私はpythonを使ってWebデータをスクラップする実際的な例を挙げます。多くの場合あなたは値のないキーを取得します、その場合あなたがあなたがdictionary ['key']を使うとエラーになる'、' return_otherwise ')に問題はありません。
同様に、リストから単一の値を取得しようとすると、list [0]ではなく、 ''。join(list)を使用します。
それが役に立てば幸い。
[編集]これは実用的な例です。
たとえば、あなたが解析する必要があるJOSNファイルを返すAPIを呼び出しているとしましょう。最初の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条件を指定するのと同じ
目的は、キーが見つからない場合にデフォルト値を指定できることです。これは非常に便利です。
dictionary.get("Name",'harry')
この機能はどのような目的に役立ちますか?
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
なぜdict [key]ではなくdict.get(key)なのでしょうか。
dict[key]
と比較すると、dict.get
はキーを探すときの代替値を提供します。
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'
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
は上記の不当なコードを避けるためのオプションのデフォルト値を導入しています。
dict.get
には、辞書にキーがない場合に例外を処理するための追加のデフォルト値オプションがあります。
キーが存在しない場合、dict.get
はデフォルトでは何も返しませんが、2番目の引数を指定すると、キーが存在しない場合はそれを返します。
キーが存在しない場合、OTOH dict[key]
はKeyError
を送出します。
これが例です(コメントを読む):
>>> d={'a':[1,2,3],'b':[4,5,6]} # Create a dictionary
>>> d['c'] # Hoops, error key does not exist
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
d['c']
KeyError: 'c'
>>> d.get('c') # no error because of `get`, so nothing returned
>>> print(d.get('c')) # i print it, oh `None` is the output
None
>>> d.get('c',100) # Okay now i set second argument's value to `100`, hoopa output is `100`
100
>>> d['a'] # Works, key exist
[1, 2, 3]
>>> d.get('a') # work too, key exist
[1, 2, 3]
.get()を使用する際の注意点:
辞書に.get()
の呼び出しで使用されるキーが含まれ、その値がNone
である場合、.get()
は、2番目の値が指定されていてもNone
を返します。
たとえば、次の例は、予想される「alt_value」ではなく、None
を返します。
d = {'key': None}
d.get('key', 'alt_value')
.get()
の2番目の値は、指定されたキーが辞書にない場合にのみ返され、その呼び出しの戻り値がNone
である場合には返されません。
用途に応じて、この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'