2012-09-30 22 views
108

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

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

आप शायद यहां वर्णित व्यवहार को मार रहे हैं: http://docs.python.org/reference/expressions.html#not-in, वह आपको लिखने देता है 'यदि कोई millimoose

+3

@millimoose काम करता है: हाँ, मैंने कभी भी "तुलना" ऑपरेटर के रूप में 'इन' के बारे में सोचा नहीं। : \ – Mehrdad

+0

हाय [पाइथन दुभाषिया में किस प्रकार का पार्सर उपयोग किया जाता है?] (Http://stackoverflow.com/questions/15532616/what-type-of-parser-is-used-in-python-interpreter) –

उत्तर

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

वाह! ! +1 यह आश्चर्यजनक है, बहुत बहुत धन्यवाद! यह वास्तव में आसान दिखता है, अगर केवल मुझे इसके बारे में पता था! क्या आपको पता है कि यह दस्तावेज़ीकरण में कहां है? मैंने [देखा] (http://docs.python.org/reference/expressions.html#boolean-operations) लेकिन यह सुझाव दिया गया कुछ भी नहीं मिला! – Mehrdad

+1

'गलत' के बजाय 'गलत' का उपयोग किया जा सकता है। – jfs

+1

@ जेएफ। सेबेस्टियन धन्यवाद, तय है कि। –

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' 

इसके अलावा ऊपर पहला नियम प्रदर्शित करने के लिए, इन बयानों कि यह सच है के रूप में मूल्यांकित कर रहे हैं।

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

From the documentation:

तुलना मनमाने ढंग से श्रृंखलित जा सकता है, जैसे, x < y < = जेड एक्स < y और 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 देखें)

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