मेरे पास सेट की एक सूची है:
setlist = [s1,s2,s3...]
मुझे s1 want s2 ∩ s3 चाहिए ...
मैं इसे जोड़ीदार की एक श्रृंखला प्रदर्शन करके करने के लिए एक फ़ंक्शन लिख सकता हूं s1.intersection(s2)
, आदि।
क्या कोई अनुशंसित, बेहतर या अंतर्निहित तरीका है?
मेरे पास सेट की एक सूची है:
setlist = [s1,s2,s3...]
मुझे s1 want s2 ∩ s3 चाहिए ...
मैं इसे जोड़ीदार की एक श्रृंखला प्रदर्शन करके करने के लिए एक फ़ंक्शन लिख सकता हूं s1.intersection(s2)
, आदि।
क्या कोई अनुशंसित, बेहतर या अंतर्निहित तरीका है?
जवाबों:
पायथन संस्करण 2.6 से आप पर कई तर्कों का उपयोग कर सकते हैं set.intersection()
, जैसे
u = set.intersection(s1, s2, s3)
यदि सेट एक सूची में हैं, तो इसका अनुवाद इस प्रकार होता है:
u = set.intersection(*setlist)
सूची विस्तार कहां *a_list
है
ध्यान दें कि set.intersection
है नहीं एक स्थिर विधि है, लेकिन इस सूची के बाकी के साथ पहला सेट के चौराहे लागू करने के लिए कार्यात्मक संकेतन का उपयोग करता है। इसलिए यदि तर्क सूची खाली है तो यह विफल हो जाएगी।
2.6 के रूप में, set.intersection
मनमाने ढंग से कई पुनरावृत्तियों लेता है।
>>> s1 = set([1, 2, 3])
>>> s2 = set([2, 3, 4])
>>> s3 = set([2, 4, 6])
>>> s1 & s2 & s3
set([2])
>>> s1.intersection(s2, s3)
set([2])
>>> sets = [s1, s2, s3]
>>> set.intersection(*sets)
set([2])
स्पष्ट रूप set.intersection
से आप यहां क्या चाहते हैं, लेकिन कभी भी आपको "इन सभी का योग", "इन सभी का उत्पाद ले लो", "इन सभी का xor लें", जो आप देख रहे हैं, के सामान्यीकरण की आवश्यकता है। reduce
समारोह:
from operator import and_
from functools import reduce
print(reduce(and_, [{1,2,3},{2,3,4},{3,4,5}])) # = {3}
या
print(reduce((lambda x,y: x&y), [{1,2,3},{2,3,4},{3,4,5}])) # = {3}
यदि आपके पास पायथन 2.6 या उच्चतर नहीं है, तो विकल्प लूप के लिए एक स्पष्ट लिखना है:
def set_list_intersection(set_list):
if not set_list:
return set()
result = set_list[0]
for s in set_list[1:]:
result &= s
return result
set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print set_list_intersection(set_list)
# Output: set([1])
आप यह भी उपयोग कर सकते हैं reduce
:
set_list = [set([1, 2]), set([1, 3]), set([1, 4])]
print reduce(lambda s1, s2: s1 & s2, set_list)
# Output: set([1])
हालांकि, कई पायथन प्रोग्रामर इसे नापसंद करते हैं, जिसमें स्वयं गुइडो भी शामिल हैं :
लगभग 12 साल पहले, पायथन एक्वायर्ड लैम्ब्डा, कम (), फिल्टर () और मैप (), शिष्टाचार (मेरा मानना है) एक लिस्प हैकर है जो उनसे चूक गया और काम करने वाले पैच प्रस्तुत किए। लेकिन, पीआर मूल्य के बावजूद, मुझे लगता है कि इन सुविधाओं को पायथन 3000 से काटा जाना चाहिए।
तो अब कम करें ()। यह वास्तव में वह है जिसे मैंने हमेशा सबसे अधिक नफरत किया है, क्योंकि, कुछ उदाहरणों के अलावा + या *, लगभग हर बार जब मैं एक गैर-तुच्छ फ़ंक्शन तर्क के साथ कम () कॉल देखता हूं, तो मुझे पेन और पेपर को हथियाने की आवश्यकता होती है आरेख क्या वास्तव में उस फ़ंक्शन में खिलाया जा रहा है इससे पहले कि मैं समझता हूं कि कम () क्या करना चाहिए। तो मेरे दिमाग में, कम करने की प्रयोज्यता () साहचर्य ऑपरेटरों के लिए बहुत सीमित है, और अन्य सभी मामलों में संचय लूप को स्पष्ट रूप से लिखना बेहतर है।
result
कि खाली होने पर आप अपना लूप तोड़कर ऑप्टिमाइज़ कर सकते हैं ।
यहाँ मैं कई सेट चौराहों के लिए एक सामान्य कार्य की पेशकश कर रहा हूँ जो उपलब्ध सर्वोत्तम विधि का लाभ उठाने की कोशिश कर रहा है:
def multiple_set_intersection(*sets):
"""Return multiple set intersection."""
try:
return set.intersection(*sets)
except TypeError: # this is Python < 2.6 or no arguments
pass
try: a_set= sets[0]
except IndexError: # no arguments
return set() # return empty set
return reduce(a_set.intersection, sets[1:])
गुइडो को नापसंद हो सकता है reduce
, लेकिन मैं इसे पसंद कर रहा हूँ :)
sets
एक्सेस करने sets[0]
और पकड़ने की कोशिश करने के बजाय लंबाई की जांच करनी चाहिए IndexError
।
a_set
अंतिम रिटर्न में उपयोग किया जाता है।
return reduce(sets[0], sets[1:]) if sets else set()
?
try
/ a पर भरोसा करने except
से बचना चाहिए यदि आप कर सकते हैं। यह एक कोड गंध है, अक्षम है, और अन्य समस्याओं को छिपा सकता है।
reduce
"सहयोगी ऑपरेटरों के लिए सीमित है", जो इस मामले में लागू है।reduce
यह पता लगाना बहुत मुश्किल है, लेकिन&
इतना बुरा नहीं है।