2010-02-26 5 views
17

जब एक सूची की तरह के साथ एक टपल की तुलना ...पायथन: सूचियों और टुपल्स के बीच तुलना क्यों समर्थित नहीं है?

>>> [1,2,3] == (1,2,3) 
False 
>>> [1,2,3].__eq__((1,2,3)) 
NotImplemented 
>>> (1,2,3).__eq__([1,2,3]) 
NotImplemented 

... अजगर नहीं उन्हें गहरे तुलना के रूप में (1,2,3) == (1,2,3) के साथ किया है।

तो इसका कारण क्या है? क्या ऐसा इसलिए है क्योंकि म्यूटेबल सूची किसी भी समय (थ्रेड-सुरक्षा मुद्दों) या क्या बदल सकती है?

(मुझे पता है, जहां इस CPython में कार्यान्वित किया जाता है, तो जवाब कृपया नहीं जहां, लेकिन क्यों इसे लागू किया जाता है।)

+4

एक सूची एक tuple और इसके विपरीत नहीं है। वे अलग-अलग प्रकार हैं। '[] ==()' 'गलत 'वापस आ जाएगा। – jathanism

+0

यह भी देखें: http://stackoverflow.com/questions/12135264/what-are-the-best-ways-to-compare-the-contents-of-two-list-like-objects/12135322#12135322 – Erik

उत्तर

19

आप कभी भी "डाली" कर सकते हैं यह

>>> tuple([1, 2]) == (1, 2) 
True 

ध्यान रखें कि पाइथन, उदाहरण के लिए जावास्क्रिप्ट, is stronglytyped, और कुछ (अधिकांश?) हम इसे इस तरह पसंद करते हैं।

+2

वास्तव में वह वास्तव में सबसे अच्छा तरीका है। – jathanism

+2

मुझे लगता है कि हम में से अधिकांश इसे इस तरह पसंद करते हैं। –

+0

मुझे लगता है कि मजबूत टाइपिंग का विचार वास्तव में यहां मायने रखता है, इसलिए मैं आपके उत्तर को सही मानूंगा। – AndiDog

7

सूचियों की तुलना करने में सक्षम नहीं होने के लिए कोई तकनीकी कारण नहीं है; यह पूरी तरह से अर्थशास्त्र द्वारा संचालित एक डिजाइन निर्णय है। सबूत है कि यह धागा सुरक्षा से संबंधित नहीं है के लिए, आप अन्य सूचियों के लिए सूचियों की तुलना कर सकते हैं:

>>> l1 = [1, 2, 3] 
>>> l2 = [1, 2, 3] 
>>> l1 == l2 
True 
>>> id(l1) == id(l2) 
False 

यह उपयोगकर्ताओं को सीधे सूचियों और tuples तुलना करने के लिए अनुमति देने के लिए उचित लगता है, लेकिन फिर आप अन्य प्रश्न के साथ अंत: चाहिए उपयोगकर्ता को सूचियों और कतारों की तुलना करने की अनुमति दी जा सकती है? इटरेटर प्रदान करने वाली किसी भी दो वस्तुओं के बारे में क्या? निम्नलिखित के बारे में क्या?

>>> s = set([('x', 1), ('y', 2)]) 
>>> d = dict(s) 
>>> s == d # This doesn't work 
False 

यह जटिल रूप से जटिल हो सकता है। भाषा डिजाइनरों ने इस मुद्दे को पहचाना, और इसे अलग-अलग संग्रह प्रकारों को एक दूसरे के साथ सीधे तुलना करने से रोकने के लिए से बचाया।

ध्यान दें कि सरल समाधान (टुपल से एक नई सूची बनाने और उनकी तुलना करने के लिए) आसान लेकिन अक्षम है। आप मदों की बड़ी संख्या के साथ काम कर रहे हैं, तो आप की तरह कुछ के साथ बेहतर कर रहे हैं:

def compare_sequences(iter1, iter2): 
    iter1, iter2 = iter(iter1), iter(iter2) 
    for i1 in iter1: 
     try: 
      i2 = next(iter2) 
     except StopIteration: 
      return False 

     if i1 != i2: 
      return False 

    try: 
     i2 = next(iter2) 
    except StopIteration: 
     return True 

    return False 

यह, किसी भी दो दृश्यों पर काम कर जटिलता में एक स्पष्ट कीमत पर का लाभ दिया है।


मैं ध्यान दें कि सेट और frozensets के लिए एक अपवाद है। और इसमें कोई संदेह नहीं है कि कुछ अन्य मुझे पता नहीं है। भाषा डिजाइनर शुद्धवादी हैं, सिवाय इसके कि यह व्यावहारिक होने का भुगतान करता है।

+0

+1 बहुत अच्छे अंक, धन्यवाद! – AndiDog

+3

दो अनुक्रमों की तुलना करने के लिए, अगली/स्टॉपइटरेशन हुप्स के माध्यम से कूदने की कोई आवश्यकता नहीं है। सभी (i1 == i2 i1 के लिए i2, i2 itertools.izip_longest (iter1, iter2, fillvalue = ऑब्जेक्ट()) में) –

संबंधित मुद्दे