私は次のようなことをしたいです:
foo = {'foo':1,'zip':2,'zam':3,'bar':4}
if ("foo","bar") in foo:
#do stuff
「foo」と「bar」の両方がdict fooにあるかどうかを確認するにはどうすればよいですか?
私は次のようなことをしたいです:
foo = {'foo':1,'zip':2,'zam':3,'bar':4}
if ("foo","bar") in foo:
#do stuff
「foo」と「bar」の両方がdict fooにあるかどうかを確認するにはどうすればよいですか?
回答:
さて、あなたはこれを行うことができます:
>>> if all (k in foo for k in ("foo","bar")):
... print "They're there!"
...
They're there!
set
が優れています。いつものように...それを測定してください!-)
if {"foo", "bar"} <= myDict.keys(): ...
まだPython 2を使用している場合は、次のことができます
if {"foo", "bar"} <= myDict.viewkeys(): ...
まだ2.6未満の非常に古いPythonを使用している場合はset
、dictを呼び出すことができますが、dict全体を繰り返し処理してセットを構築するので、処理が遅くなります。
if set(("foo", "bar")) <= set(myDict): ...
set(("foo","bar")) <= myDict.keys()
では、一時的なセットを回避できるため、はるかに高速です。私のテストでは、クエリが10アイテムのときにすべてを使用した場合とほぼ同じ速度です。ただし、クエリが大きくなるほど遅くなります。
if {'foo', 'bar'} <= set(myDict): ...
DとQに独自の値を入力します
>>> from timeit import Timer
>>> setup='''from random import randint as R;d=dict((str(R(0,1000000)),R(0,1000000)) for i in range(D));q=dict((str(R(0,1000000)),R(0,1000000)) for i in range(Q));print("looking for %s items in %s"%(len(q),len(d)))'''
>>> Timer('set(q) <= set(d)','D=1000000;Q=100;'+setup).timeit(1)
looking for 100 items in 632499
0.28672504425048828
#This one only works for Python3
>>> Timer('set(q) <= d.keys()','D=1000000;Q=100;'+setup).timeit(1)
looking for 100 items in 632084
2.5987625122070312e-05
>>> Timer('all(k in d for k in q)','D=1000000;Q=100;'+setup).timeit(1)
looking for 100 items in 632219
1.1920928955078125e-05
d.viewkeys()
作成する必要がありset(q) <= d.viewkeys()
ます。
Python 2.7.5
持ちd.keys()
すぎ方法を。
set(q) <= ...
TypeError: can only compare to a set
。ごめんなさい!:))
d.viewkeys() >= set(q)
。順序が重要な理由を見つけるためにここに来ました!
左側をセットで囲む必要はありません。あなたはこれを行うことができます:
if {'foo', 'bar'} <= set(some_dict):
pass
これは、all(k in d...)
ソリューションよりもパフォーマンスが優れています。
セットの使用:
if set(("foo", "bar")).issubset(foo):
#do stuff
または:
if set(("foo", "bar")) <= set(foo):
#do stuff
set(d)
と同じですset(d.keys())
(d.keys()
構築する中間リストなし)
これはどう:
if all([key in foo for key in ["foo","bar"]]):
# do stuff
pass
all
。
私はAlex Martelliの答えが好きですが、私にはPythonicには思えません。つまり、Pythonicであることの重要な部分は、簡単に理解できることだと思いました。その目標で<=
は、理解するのは簡単ではありません。
それはより多くのキャラクターですが、issubset()
カール・フォイトランドの答えが示唆するように使用する方が理解しやすいです。そのメソッドは、引数としてディクショナリを使用できるため、短く理解できる解決策は次のとおりです。
foo = {'foo': 1, 'zip': 2, 'zam': 3, 'bar': 4}
if set(('foo', 'bar')).issubset(foo):
#do stuff
の方が短いので{'foo', 'bar'}
、の代わりに使用したいと思いset(('foo', 'bar'))
ます。しかし、それはそれほど理解できませんし、中括弧は辞書であると簡単に混同されると思います。
Alex Martelliのソリューション set(queries) <= set(my_dict)
は最短のコードですが、最速ではない場合があります。Q = len(queries)およびD = len(my_dict)と仮定します。
これはO(Q)+ O(D)を使用して2つのセットを作成し、次に(1つは期待しています!)O(min(Q、D))だけを使用してサブセットテストを実行します-もちろん、Pythonがルックアップを設定するとしますis O(1)-これは最悪のケースです(答えがTrueの場合)。
hughdbrown(et al?)のジェネレーターソリューションall(k in my_dict for k in queries)
は、最悪の場合のO(Q)です。
複雑な要因:
(1)セットベースのガジェットのループはすべてC速度で実行されますが、任意ベースのガジェットはバイトコード上でループします。
(2)セットベースのガジェットはそのような制御を許可しないのに対し、任意ベースのガジェットの呼び出し元は、クエリ項目の順序付けに失敗する確率の知識を使用できる場合があります。
いつものように、速度が重要である場合、運用条件下でのベンチマークは良い考えです。
あなたは使用することができます)(.issubsetにも
>>> {"key1", "key2"}.issubset({"key1":1, "key2":2, "key3": 3})
True
>>> {"key4", "key2"}.issubset({"key1":1, "key2":2, "key3": 3})
False
>>>
ラムダを使用するのはどうですか?
if reduce( (lambda x, y: x and foo.has_key(y) ), [ True, "foo", "bar"] ): # do stuff
あなたがしたい場合:
次に:
from operator import itemgetter
foo = {'foo':1,'zip':2,'zam':3,'bar':4}
keys = ("foo","bar")
getter = itemgetter(*keys) # returns all values
try:
values = getter(foo)
except KeyError:
# not both keys exist
pass
>>> if 'foo' in foo and 'bar' in foo:
... print 'yes'
...
yes
Jason、()はPythonでは必要ありません。
私の考えでは、与えられたすべてのオプションを理解しやすい2つの方法があります。したがって、私の主な基準は、非常に読みやすいコードであり、非常に高速なコードではありません。コードを理解しやすくするために、私は与えられた可能性を好む:
以下のテストでは、「var <= var2.keys()」がより高速に実行されるという事実から、私はこれを優先します。
import timeit
timeit.timeit('var <= var2.keys()', setup='var={"managed_ip", "hostname", "fqdn"}; var2= {"zone": "test-domain1.var23.com", "hostname": "bakje", "api_client_ip": "127.0.0.1", "request_data": "", "request_method": "GET", "request_url": "hvar2p://127.0.0.1:5000/test-domain1.var23.com/bakje", "utc_datetime": "04-Apr-2019 07:01:10", "fqdn": "bakje.test-domain1.var23.com"}; var={"managed_ip", "hostname", "fqdn"}')
0.1745898080000643
timeit.timeit('var.issubset(var2)', setup='var={"managed_ip", "hostname", "fqdn"}; var2= {"zone": "test-domain1.var23.com", "hostname": "bakje", "api_client_ip": "127.0.0.1", "request_data": "", "request_method": "GET", "request_url": "hvar2p://127.0.0.1:5000/test-domain1.var23.com/bakje", "utc_datetime": "04-Apr-2019 07:01:10", "fqdn": "bakje.test-domain1.var23.com"}; var={"managed_ip", "hostname", "fqdn"};')
0.2644960229999924
>>> ok
{'five': '5', 'two': '2', 'one': '1'}
>>> if ('two' and 'one' and 'five') in ok:
... print "cool"
...
cool
これはうまくいくようです
()
最初に評価し、その結果にされるだろうTrue
、その後かどうかを確認思われます、True in ok
。これは実際にはどのように機能しますか?