पायथन में "इन" की सहयोगीता?


107

मैं एक अजगर पार्सर बना रहा हूं, और यह वास्तव में मुझे भ्रमित कर रहा है:

>>>  1 in  []  in 'a'
False

>>> (1 in  []) in 'a'
TypeError: 'in <string>' requires string as left operand, not bool

>>>  1 in ([] in 'a')
TypeError: 'in <string>' requires string as left operand, not list

सहानुभूति, आदि के संबंध में पाइथन में वास्तव में "इन" कैसे काम करता है?

इनमें से कोई भी दो भाव समान व्यवहार क्यों नहीं करते हैं?


6
आप शायद यहां बताए गए व्यवहार को मार रहे हैं: docs.python.org/reference/expressions.html#not-in , जो आपको लिखने देता है if a < b < c:और इसे सहज रूप से काम करने देता है
मिलीमोसे

3
@millimoose: हाँ, inमुझे लगता है मैं एक "तुलना" ऑपरेटर के रूप में कभी नहीं सोचा था । : \
user541686

जवाबों:


123

1 in [] in 'a'के रूप में मूल्यांकन किया है (1 in []) and ([] in 'a')

चूंकि पहली शर्त ( 1 in []) है False, इसलिए पूरी स्थिति का मूल्यांकन किया जाता है False; ([] in 'a')वास्तव में कभी मूल्यांकन नहीं किया जाता है, इसलिए कोई त्रुटि नहीं उठाई जाती है।

यहाँ बयान परिभाषाएँ हैं:

In [121]: def func():
   .....:     return 1 in [] in 'a'
   .....: 

In [122]: dis.dis(func)
  2           0 LOAD_CONST               1 (1)
              3 BUILD_LIST               0
              6 DUP_TOP             
              7 ROT_THREE           
              8 COMPARE_OP               6 (in)
             11 JUMP_IF_FALSE            8 (to 22)  #if first comparison is wrong 
                                                    #then jump to 22, 
             14 POP_TOP             
             15 LOAD_CONST               2 ('a')
             18 COMPARE_OP               6 (in)     #this is never executed, so no Error
             21 RETURN_VALUE         
        >>   22 ROT_TWO             
             23 POP_TOP             
             24 RETURN_VALUE        

In [150]: def func1():
   .....:     return (1 in  []) in 'a'
   .....: 

In [151]: dis.dis(func1)
  2           0 LOAD_CONST               1 (1)
              3 LOAD_CONST               3 (())
              6 COMPARE_OP               6 (in)   # perform 1 in []
              9 LOAD_CONST               2 ('a')  # now load 'a'
             12 COMPARE_OP               6 (in)   # compare result of (1 in []) with 'a'
                                                  # throws Error coz (False in 'a') is
                                                  # TypeError
             15 RETURN_VALUE   



In [153]: def func2():
   .....:     return 1 in ([] in 'a')
   .....: 

In [154]: dis.dis(func2)
  2           0 LOAD_CONST               1 (1)
              3 BUILD_LIST               0
              6 LOAD_CONST               2 ('a') 
              9 COMPARE_OP               6 (in)  # perform ([] in 'a'), which is 
                                                 # Incorrect, so it throws TypeError
             12 COMPARE_OP               6 (in)  # if no Error then 
                                                 # compare 1 with the result of ([] in 'a')
             15 RETURN_VALUE        

वाह !! +1 यह अद्भुत है, बहुत बहुत धन्यवाद! यह वास्तव में आसान लग रहा है, अगर केवल मुझे इसके बारे में पता था! क्या आपको पता है कि यह प्रलेखन में कहां है? मैंने देखा, लेकिन ऐसा कुछ भी नहीं मिला जो यह सुझाए!
user541686

1
ध्यान दें: []गलत है, लेकिन []नहीं है False, उदाहरण के लिए [] and anythingरिटर्न [](नहीं False)।
13

6
@Mehrdad की जाँच करें अजगर disassembler उस के साथ इस्तेमाल किया गया था IPython इस उत्पादन उत्पन्न करने के लिए।
जेफ फेरलैंड

डनो ने पायथन के किस संस्करण को उत्पन्न किया, लेकिन पायथन 3.2 में जाहिरा तौर पर एक नया बायटेकोड है: JUMP_IF_FALSE_OR_POP, जो 13 से 12 तक एक निर्देश द्वारा अनुक्रम को छोटा करता है। कूल जवाब - धन्यवाद !!
डेव

@Dave यह अजगर 2.6.6 (IPython)
अश्विनी चौधरी

22

पायथन जंजीरों की तुलना के साथ विशेष चीजें करता है।

निम्नलिखित का मूल्यांकन अलग तरीके से किया जाता है:

x > y > z   # in this case, if x > y evaluates to true, then
            # the value of y is being used to compare, again,
            # to z

(x > y) > z # the parenth form, on the other hand, will first
            # evaluate x > y. And, compare the evaluated result
            # with z, which can be "True > z" or "False > z"

हालांकि दोनों मामलों में, यदि पहली तुलना है False, तो बाकी के बयान पर ध्यान नहीं दिया जाएगा।

आपके विशेष मामले के लिए,

1 in [] in 'a'   # this is false because 1 is not in []

(1 in []) in a   # this gives an error because we are
                 # essentially doing this: False in 'a'

1 in ([] in 'a') # this fails because you cannot do
                 # [] in 'a'

ऊपर दिए गए पहले नियम को प्रदर्शित करने के लिए, ये कथन हैं जो True का मूल्यांकन करते हैं।

1 in [1,2] in [4,[1,2]] # But "1 in [4,[1,2]]" is False

2 < 4 > 1               # and note "2 < 1" is also not true

अजगर ऑपरेटरों की प्राथमिकता: http://docs.python.org/reference/expressions.html#summary


11

प्रलेखन से:

तुलनाएँ मनमाने ढंग से की जा सकती हैं, उदाहरण के लिए, x <y <= z, x <y और y <= z के बराबर है, सिवाय इसके कि y का केवल एक बार मूल्यांकन किया जाता है (लेकिन दोनों मामलों में z का मूल्यांकन तब नहीं किया जाता है जब x <y पाया जाता है झूठा होना)।

इसका क्या मतलब है, कि इसमें कोई जुड़ाव नहीं है x in y in z!

निम्नलिखित समतुल्य हैं:

1 in  []  in 'a'
# <=>
middle = []
#            False          not evaluated
result = (1 in middle) and (middle in 'a')


(1 in  []) in 'a'
# <=>
lhs = (1 in []) # False
result = lhs in 'a' # False in 'a' - TypeError


1 in  ([] in 'a')
# <=>
rhs = ([] in 'a') # TypeError
result = 1 in rhs

3

संक्षिप्त उत्तर, चूंकि लंबे समय से पहले से ही कई बार यहां और उत्कृष्ट तरीके से दिया गया है, यह है कि बूलियन अभिव्यक्ति को कम-प्रसारित किया जाता है , यह मूल्यांकन बंद कर दिया है जब झूठे या इसके विपरीत में सच का परिवर्तन आगे के मूल्यांकन से नहीं हो सकता है।

(देखें http://en.wikipedia.org/wiki/Short-circuit_evaluation )

यह एक उत्तर के रूप में थोड़ा छोटा (कोई दंडित इरादा नहीं) हो सकता है, लेकिन जैसा कि उल्लेख किया गया है, अन्य सभी स्पष्टीकरण यहां पहले से ही काफी अच्छी तरह से किया गया है, लेकिन मुझे लगा कि इस शब्द का उल्लेख करने योग्य है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.