मैं कैसे जांच सकता हूं कि एक ही पास में कई कुंजियाँ एक तानाशाही में हैं?


जवाबों:


363

ठीक है, आप ऐसा कर सकते हैं:

>>> if all (k in foo for k in ("foo","bar")):
...     print "They're there!"
...
They're there!

10
+1, मुझे यह ग्रेग के उत्तर से बेहतर लगता है क्योंकि यह अधिक संक्षिप्त और तेज़ है (अप्रासंगिक अस्थायी सूची की कोई इमारत नहीं है, और शॉर्ट-सर्कुलेटिंग का पूरा शोषण है)।
एलेक्स मार्टेली

4
मुझे सब पसंद है () और कोई भी ()। वे इतने सारे एल्गोरिदम को बहुत क्लीनर बनाते हैं।
हुग्डब्रोर्न

मैं अंततः इस समाधान का उपयोग कर समाप्त हो गया। यह बड़े डेटासेट के लिए सबसे अच्छा लग रहा था। जब 25 या 30 कुंजी कहने के लिए जाँच कर रहा हो।

4
यह शॉर्ट-सर्कुलेटिंग के लिए एक अच्छा समाधान है, खासकर यदि परीक्षण अधिक बार विफल हो जाता है; जब तक आप ब्याज की कुंजी का सेट सिर्फ एक बार बना सकते हैं और इसे कई बार जांच सकते हैं, जिस स्थिति में setयह बेहतर है। हमेशा की तरह ... इसे
नापें

मैं इसका इस्तेमाल करता हूं जब भी यह "सामान्य" तरीके से अच्छा लगता है, सभी के साथ या या ... यह भी अच्छा है क्योंकि आप "सभी" या "किसी भी" का उपयोग कर सकते हैं ... इसके अलावा आप या तो हो सकते हैं " k in foo "या" k not in foo "उस परीक्षण के आधार पर जिसे आप करने की कोशिश कर रहे हैं
Terence Honles

123
if {"foo", "bar"} <= myDict.keys(): ...

यदि आप अभी भी पायथन 2 पर हैं, तो आप कर सकते हैं

if {"foo", "bar"} <= myDict.viewkeys(): ...

यदि आप अभी भी एक बहुत पुराने अजगर <= 2.6 पर हैं, तो आप setडिक्टेट पर कॉल कर सकते हैं , लेकिन यह सेट बनाने के लिए पूरे डिक्टेट पर पुनरावृति करेगा, और यह धीमा है:

if set(("foo", "bar")) <= set(myDict): ...

अच्छा लग रहा है! केवल एक चीज जो मुझे पसंद नहीं है वह यह है कि आपको अस्थायी सेट बनाने होंगे, लेकिन यह बहुत कॉम्पैक्ट है। तो मुझे कहना होगा ... सेट का अच्छा उपयोग!
टेरेंस हॉनल्स

17
अजगर 3 में आप कह सकते हैं कि set(("foo","bar")) <= myDict.keys()अस्थायी सेट से बचा जाता है, इसलिए बहुत तेज है। मेरे परीक्षण के लिए यह सब उसी गति के बारे में है जब क्वेरी 10 आइटम थी। यह धीमी हो जाती है क्योंकि क्वेरी बड़ी हो जाती है।
जॉन ला रूय

1
मैंने उत्तर के रूप में अपने कुछ परीक्षण पोस्ट किए हैं। stackoverflow.com/questions/1285911/…
जॉन ला रूय

30
if {'foo', 'bar'} <= set(myDict): ...
बोरिस राचफ

11
किसी के लिए भी यह क्यों काम करता है, यह सोचकर: ऑपरेटर <= issubset () विधि: docs.python.org/3/library/stdtypes.html#set-types-set-frozenset
edepe

41

विकल्पों में से 3 के लिए सरल बेंचमार्किंग रिग।

डी और क्यू के लिए अपने स्वयं के मूल्यों में रखो


>>> 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

4
पायथन 2.7 d.viewkeys()को बनाना है set(q) <= d.viewkeys()
मार्टिन पीटर्स

Python 2.7.5है d.keys()विधि भी।
इवान खरलामोव

3
@IvanKharlamov, लेकिन पायथन 2 में, यह एक ऐसी वस्तु को वापस नहीं करता है जो संगत हैset(q) <= ...
जॉन ला रूय

1
मेरा बुरा, तुम बिल्कुल हाजिर हो: यह लौटता है TypeError: can only compare to a set। माफ़ करना! :))
इवान खारलामोव

1
पायथन 2 के लिए ऑर्डर को स्विच करें d.viewkeys() >= set(q):। मैं यह जानने की कोशिश कर रहा था कि आदेश क्यों मायने रखता है!
विड्रैक

34

आपको एक सेट में बाईं ओर लपेटने की आवश्यकता नहीं है। आप ऐसा कर सकते हैं:

if {'foo', 'bar'} <= set(some_dict):
    pass

यह भी all(k in d...)समाधान से बेहतर प्रदर्शन करता है ।


2
यह भी सभी (डी में कश्मीर ...) समाधान की तुलना में बेहतर प्रदर्शन करता है। मैंने इसे एक संपादन के रूप में सुझाया था, लेकिन यह एक टिप्पणी जोड़ने के लिए बेहतर था इस आधार पर इसे अस्वीकार कर दिया गया था । तो यहाँ मुझे बस ऐसा कर रहा है
चमत्कारी

@miraculixx टिप्पणी जोड़ना बेहतर नहीं है। प्रासंगिक जानकारी को उत्तर में संपादित करना और टिप्पणियों को हटाना बेहतर है।
एंडोलिथ

1
@endolith मैं सहमत हूं, कुछ लोग स्पष्ट रूप से नहीं करते हैं जैसा कि आप अस्वीकार किए गए संपादन में देख सकते हैं कि मैंने पहली जगह में किया था। वैसे भी मेटा के लिए चर्चा यहाँ के लिए नहीं है।
चमत्कारिक मास

क्या कोई इसे समझा सकता है? मैंने इकट्ठा किया है कि {} एक सेट बनाता है, लेकिन कम-से-या-बराबर ऑपरेटर यहां कैसे काम कर रहा है?
Locane

1
@ लोकेन <= ऑपरेटर परीक्षण करता है यदि पहला सेट दूसरे सेट का सबसेट है। आप {'foo', 'bar'} भी कर सकते हैं। issubset (somedict)। सेट कार्यप्रणाली के लिए दस्तावेज यहां देखे
Meow

24

का उपयोग करते हुए सेट:

if set(("foo", "bar")).issubset(foo):
    #do stuff

वैकल्पिक रूप से:

if set(("foo", "bar")) <= set(foo):
    #do stuff

2
सेट (d) जैसा कि मैंने अपने उत्तर में इस्तेमाल किया है, सेट (d.keys ()) की तरह है, लेकिन तेज, छोटा और मैं शैलीगत रूप से बेहतर कहूंगा।
एलेक्स मार्टेली

set(d)के रूप में ही है set(d.keys())(मध्यवर्ती सूची के बिना जो d.keys()निर्माण करता है)
जोचन रिट्जेल

11

इस बारे में कैसा है:

if all([key in foo for key in ["foo","bar"]]):
    # do stuff
    pass

8
वास्तव में, न केवल अनावश्यक, सकारात्मक रूप से हानिकारक, क्योंकि वे सामान्य लघु-संचार व्यवहार को बाधित करते हैं all
एलेक्स मार्टेली


9

जबकि मुझे एलेक्स मार्टेली का जवाब पसंद है, यह मुझे पाइथोनिक नहीं लगता। यही है, मैंने सोचा कि पायथोनिक होने का एक महत्वपूर्ण हिस्सा आसानी से समझा जा सकता है। उस लक्ष्य के साथ,<= समझना आसान नहीं है।

हालांकि यह अधिक वर्ण है, issubset()कार्ल वायगटलैंड के उत्तर के रूप में सुझाए गए उपयोग से अधिक समझ में आता है। चूँकि वह विधि किसी शब्दकोश को एक तर्क के रूप में उपयोग कर सकती है, एक छोटा, समझने योग्य समाधान है:

foo = {'foo': 1, 'zip': 2, 'zam': 3, 'bar': 4}

if set(('foo', 'bar')).issubset(foo):
    #do stuff

मैं इसके {'foo', 'bar'}स्थान पर उपयोग करना चाहता हूं set(('foo', 'bar')), क्योंकि यह छोटा है। हालांकि, यह समझ में नहीं आता है और मुझे लगता है कि शब्दकोष होने के नाते ब्रेसिज़ बहुत आसानी से भ्रमित हो जाते हैं।


2
मुझे लगता है कि एक बार समझने के बाद कि इसका क्या मतलब है।
बोबोर्ट ऑक्ट

यह प्रलेखन में एक पर्याय के रूप में है .issubset()। मुझे लगता है कि पायथन डॉक्यूमेंटेशन में यह डिफ़ॉल्ट रूप से पायथोनिक है।
ingyhere

4

एलेक्स मार्टेली का समाधान set(queries) <= set(my_dict) सबसे छोटा कोड है, लेकिन यह सबसे तेज़ नहीं हो सकता है। क्यू = लेन (प्रश्न) और डी = लेन (my_dict) मान लें।

यह दो सेट बनाने के लिए O (Q) + O (D) लेता है, और फिर (एक उम्मीद!) केवल O (min (Q, D)) को सब्सेट टेस्ट करने के लिए करता है - यह मानते हुए कि पायथन सेट लुक-अप करता है। is O (1) - यह सबसे खराब स्थिति है (जब उत्तर सत्य हो)।

Hughdbrown (एट अल?) का जनरेटर समाधान all(k in my_dict for k in queries) का सबसे खराब स्थिति O (Q) है।

जटिल कारक:
(1) सेट-आधारित गैजेट में छोरों को सभी सी-स्पीड पर किया जाता है, जबकि कोई भी आधारित गैजेट बाईटेकोड पर लूपिंग होता है।
(2) किसी भी आधारित गैजेट का कॉलर क्वेरी आइटम ऑर्डर करने के लिए विफलता के प्रायिकता के किसी भी ज्ञान का उपयोग करने में सक्षम हो सकता है जबकि सेट-आधारित गैजेट इस तरह के नियंत्रण की अनुमति नहीं देता है।

हमेशा की तरह, यदि गति महत्वपूर्ण है, तो परिचालन स्थितियों के तहत बेंचमार्किंग एक अच्छा विचार है।


1
मेरे द्वारा किए गए सभी मामलों के लिए जनरेटर तेज था। stackoverflow.com/questions/1285911/…
जॉन ला रूय


1

लैम्बडा के उपयोग के बारे में कैसे?

 if reduce( (lambda x, y: x and foo.has_key(y) ), [ True, "foo", "bar"] ): # do stuff

2
यह उत्तर केवल कार्यात्मक रूप से सही है जो कि पायथन 1.5 पर एक साधारण परिवर्तन (s / True / 1 /) के साथ काम करेगा ... लेकिन इसे इसके लिए कुछ और नहीं मिला है। और सही बात यह बेहतर होगी कि अनुक्रमिक आरजी के सामने crammed के बजाय वैकल्पिक इनिशलाइज़र arg बेहतर होगा।
जॉन मैकिन

1

मामले में आप चाहते हैं:

  • कुंजी के लिए मान भी प्राप्त करें
  • एक से अधिक तानाशाही की जाँच करें

फिर:

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

1

यह सुझाव देने के लिए नहीं कि यह कोई ऐसी चीज नहीं है जिसके बारे में आपने नहीं सोचा है, लेकिन मुझे लगता है कि सबसे सरल चीज आमतौर पर सबसे अच्छी होती है:

if ("foo" in foo) and ("bar" in foo):
    # do stuff

1
>>> if 'foo' in foo and 'bar' in foo:
...     print 'yes'
... 
yes

जेसन, () पायथन में आवश्यक नहीं हैं।


3
फिर भी वे अच्छी शैली के हो सकते हैं ... उनके बिना, मेरा सी ++ - जोड़ा हुआ मस्तिष्क हमेशा आश्चर्यचकित करता है कि अगर यह "अगर फू में 'फू (फू और बार') के रूप में व्याख्या की जाए तो:"
जेरेमी फ्रेज़र

1
मैं समझता हूं कि वे आवश्यक नहीं हैं। मुझे बस लगता है कि वे इस मामले में स्पष्टता जोड़ते हैं।
जेसन बेकर

0

बस मेरा इस पर ध्यान देना, दो विधियां हैं जो सभी दिए गए विकल्पों को समझना आसान है। तो मेरे मुख्य मानदंड में बहुत पठनीय कोड है, असाधारण रूप से तेज कोड नहीं। कोड को समझने के लिए, मैं दी गई संभावनाओं को पसंद करता हूं:

  • var <= var2.keys ()
  • var.issubset (var2)

यह तथ्य कि "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

0

यह निर्धारित करने के मामले में कि क्या केवल कुछ कुंजियाँ मेल खाती हैं, यह काम करता है:

any_keys_i_seek = ["key1", "key2", "key3"]

if set(my_dict).intersection(any_keys_i_seek):
    # code_here
    pass

एक और विकल्प खोजने के लिए कि क्या केवल कुछ कुंजियाँ मेल खाती हैं:

any_keys_i_seek = ["key1", "key2", "key3"]

if any_keys_i_seek & my_dict.keys():
    # code_here
    pass

0

यह पता लगाने के लिए एक अन्य विकल्प है कि क्या सभी चाबियाँ एक तानाशाही में हैं:

dict_to_test = { ... }  # dict
keys_sought = { "key_sought_1", "key_sought_2", "key_sought_3" }  # set

if keys_sought & dict_to_test.keys() == keys_sought: 
    # yes -- dict_to_test contains all keys in keys_sought
    # code_here
    pass

-4
>>> ok
{'five': '5', 'two': '2', 'one': '1'}

>>> if ('two' and 'one' and 'five') in ok:
...   print "cool"
... 
cool

यह काम करने लगता है


यह चतुर है और मुझे यकीन था कि यह तब तक काम नहीं करेगा जब तक कि मैं इसे स्वयं नहीं आजमाता। मुझे संदेह था ()कि पहले मूल्यांकन Trueकिया जाएगा और उसके बाद परिणाम आएगा, जो तब जांच करेगा True in ok। यह वास्तव में कैसे काम करता है ?!
डुरडेन 2.0

7
((दो ’और 'एक’ और' पांच ’), पांच’ लौटाता है, इसलिए यह वास्तव में केवल तभी जांच करता है जब 'पांच ’हुकुम पर हो
हार्डक्वेस्ट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.