2012-11-30 16 views
55

is ऑपरेटर चरों के मान, लेकिन उदाहरणों खुद को मेल नहीं खाती "है।"समझौता पायथन के ऑपरेटर

इसका वास्तव में क्या अर्थ है?

मैंने x नामक दो चर घोषित किए और y दोनों चरों में समान मान निर्दिष्ट करते हैं, लेकिन जब मैं is ऑपरेटर का उपयोग करता हूं तो यह झूठा होता है।

मुझे एक स्पष्टीकरण की आवश्यकता है। मेरा कोड यहाँ है।

x = [1, 2, 3] 
y = [1, 2, 3] 

print x is y #It prints false! 
+0

संबंधित प्रश्न http://stackoverflow.com/questions/38189660/two-variables-in-python-have-same-id-but-not-lists-or-tuples-why/38189759#38189759 – Kasramvd

उत्तर

102

आप क्या is ऑपरेटर परीक्षण गलत समझा। यह परीक्षण करता है कि क्या दो चर उसी ऑब्जेक्ट पर इंगित करते हैं, भले ही दो चर के समान मान न हो।

is operator के लिए दस्तावेज़ से

:

ऑपरेटरों is और वस्तु पहचान के लिए is not परीक्षण: x is y सच है यदि और केवल यदि x और y एक ही वस्तु है।

बजाय == ऑपरेटर का उपयोग करें:

print x == y 

यह प्रिंट Truex और y दो अलग सूचियों हैं:

x[0] = 4 
print y # prints [1, 2, 3] 
print x == y # prints False 

आप का उपयोग करते हैं id() function आप देखेंगे कि x और y अलग पहचानकर्ता:

>>> id(x) 
4401064560 
>>> id(y) 
4401098192 

लेकिन आप x को y आवंटित करने के लिए थे तो दोनों एक ही ऑब्जेक्ट को इंगित करते हैं:

>>> x = y 
>>> id(x) 
4401064560 
>>> id(y) 
4401064560 
>>> x is y 
True 

और is दोनों एक ही वस्तु हैं, यह True देता है।

+2

तो, ' ए बी है 'आईडी (ए) == आईडी (बी)' के समान है। – imallett

+1

@imallett: यह एक ही परीक्षण के लिए प्रॉक्सी है, बशर्ते आप एक आईडी में 'आईडी (ए)' स्टोर न करें और बाद में 'variable == id (B)' अभी भी काम करने की अपेक्षा करें; यदि इस दौरान 'ए' हटा दिया गया था तो' बी' को एक ही स्मृति स्थान दिया जा सकता था। –

+0

समझ में आता है, और यह भी सही बात है; 'परिवर्तनीय' पहले से मौजूद किसी चीज की संपत्ति संग्रहीत कर रहा है। रनटाइम का पता लगाने के लिए कोई रास्ता नहीं है कि बाद में उपयोग गलत है। मानक का मुख्य भाग "[id()] को इस ऑब्जेक्ट के लिए अद्वितीय और निरंतर होने की गारंटी है। इसके जीवनकाल को __ गैर-ओवरलैपिंग लाइफटाइम वाले दो ऑब्जेक्ट्स में एक ही आईडी() मान हो सकता है।" – imallett

2

एक्स एक सरणी को इंगित करता है, वाई अंक एक अलग सरणी पर इंगित करता है। वे सरणी समान हैं, लेकिन is ऑपरेटर उन पॉइंटर्स को देखेगा, जो समान नहीं हैं।

+4

अजगर संकेत नहीं है। आपको अपनी शब्दावली को कसने की जरूरत है। –

+2

यह जावा और कई अन्य भाषाओं की तरह आंतरिक रूप से करता है। वास्तव में, 'है' ऑपरेटर की कार्यक्षमता यह दिखाती है। – Neko

+4

कार्यान्वयन विवरण महत्वपूर्ण नहीं हैं। प्रलेखन शब्दावली "ऑब्जेक्ट पहचान" का उपयोग करता है। तो आपको चाहिए "ऑपरेटर ऑब्जेक्ट पहचान के लिए परीक्षण नहीं करते हैं: x है y सही है अगर केवल और यदि एक्स और वाई एक ही ऑब्जेक्ट हैं। X नहीं है, उलटा सच्चाई मूल्य उत्पन्न करता है।" –

1

यह ऑब्जेक्ट पहचान की तुलना करता है, यानी, वेरिएबल एक ही ऑब्जेक्ट को स्मृति में संदर्भित करते हैं या नहीं। यह जावा या सी में == की तरह है (पॉइंटर्स की तुलना करते समय)।

2

जैसा कि आप यहां एक छोटे से पूर्णांक में देख सकते हैं। 257 से ऊपर की संख्या एक छोटी चींटियां नहीं हैं, इसलिए इसे एक अलग वस्तु के रूप में गणना की जाती है।

इस मामले में == का उपयोग करना बेहतर है।

में अधिक जानकारी यहाँ है: http://docs.python.org/2/c-api/int.html

6

is ही सच्चा लौटाता है यदि वे वास्तव में एक ही वस्तु हो। यदि वे वही थे, तो एक में परिवर्तन दूसरे में भी दिखाई देगा। अंतर का एक उदाहरण यहां दिया गया है।

>>> x = [1, 2, 3] 
>>> y = [1, 2, 3] 
>>> print x is y 
False 
>>> z = y 
>>> print y is z 
True 
>>> print x is z 
False 
>>> y[0] = 5 
>>> print z 
[5, 2, 3] 
6

एक duplicate question से प्रेरित होकर, इस सादृश्य काम कर सकते हैं:

# - Darling, I want some pudding! 
# - There is some in the fridge. 

pudding_to_eat = fridge_pudding 
pudding_to_eat is fridge_pudding 
# => True 

# - Honey, what's with all the dirty dishes? 
# - I wanted to eat pudding so I made some. Sorry about the mess, Darling. 
# - But there was already some in the fridge. 

pudding_to_eat = make_pudding(ingredients) 
pudding_to_eat is fridge_pudding 
# => False 
+2

सिर्फ व्यक्तिगत स्वाद हो सकता है (कोई इरादा नहीं है) लेकिन मुझे यह समरूपता सहायक से अधिक भ्रमित पाया गया है और जब मुझे मेरे फ्रिज में कोई नहीं है तो मुझे पुडिंग खाने की इच्छा है :( मुझे लगता है कि मार्क रान्ससम का जवाब, और भी उबाऊ, शायद अधिक निर्देशक –

+1

@TomClose: इस सवाल पर कई अच्छे उत्तर हैं, पर्याप्त है कि लेविटी के लिए जगह है। इसके अलावा, मुझे भी हलवा चाहिए। – Amadan

23

Another duplicate पूछ क्यों दो बराबर तार आम तौर पर, समान नहीं हैं जो वास्तव में यहाँ का उत्तर नहीं मिला था:

>>> x = 'a' 
>>> x += 'bc' 
>>> y = 'abc' 
>>> x == y 
True 
>>> x is y 
False 

तो, वे एक ही स्ट्रिंग क्यों नहीं हैं? खास तौर पर इस दी:

>>> z = 'abc' 
>>> w = 'abc' 
>>> z is w 
True 

के एक बिट के लिए दूसरे भाग बंद कर दिया करते हैं। पहला व्यक्ति कैसे सच हो सकता है?

दुभाषिया को स्ट्रिंग ऑब्जेक्ट्स के लिए एक टेबल मैपिंग स्ट्रिंग मान, "इंटर्निंग टेबल" होना चाहिए, इसलिए हर बार जब आप 'abc' सामग्री के साथ एक नई स्ट्रिंग बनाने का प्रयास करते हैं, तो आप एक ही ऑब्जेक्ट वापस लेते हैं। Wikipedia में इंटर्निंग कैसे काम करता है इस पर एक और विस्तृत चर्चा है।

और पायथन में एक स्ट्रिंग इंटर्निंग टेबल है; आप sys.intern विधि के साथ मैन्युअल रूप से प्रशिक्षु तार कर सकते हैं।

वास्तव में, अजगर अनुमति लिए स्वचालित रूप से प्रशिक्षु किसी भी अपरिवर्तनीय प्रकार है, लेकिन ऐसा करने के लिए नहीं की आवश्यकता है। विभिन्न कार्यान्वयन अलग-अलग मूल्यों को प्रशिक्षित करेंगे।

सीपीथॉन (यदि आप नहीं जानते हैं कि आप किस कार्यान्वयन का उपयोग कर रहे हैं तो कार्यान्वयन का उपयोग कर रहे हैं) ऑटो इंटर्न छोटे इंटीग्रर्स और False जैसे कुछ विशेष सिंगलेट्स, लेकिन तार नहीं (या बड़े पूर्णांक, या छोटे टुपल्स, या और कुछ)। आप बहुत आसानी से देख सकते हैं:

>>> a = 0 
>>> a += 1 
>>> b = 1 
>>> a is b 
True 
>>> a = False 
>>> a = not a 
>>> b = True 
a is b 
True 
>>> a = 1000 
>>> a += 1 
>>> b = 1001 
>>> a is b 
False 

ठीक है, लेकिन क्यों z और w समान थे?

दुभाषिया स्वचालित रूप से होना शामिल नहीं है यही कारण है, कि संकलक तह मूल्यों है।

एक ही संकलन समय स्ट्रिंग एक ही मॉड्यूल में दो बार प्रकट होता है (वास्तव में क्या इसका मतलब यह है परिभाषित-यह करने के लिए एक स्ट्रिंग शाब्दिक रूप में एक ही बात नहीं है, क्योंकि r'abc', 'abc', और 'a' 'b' 'c' सभी विभिन्न शाब्दिक हैं, लेकिन मुश्किल है एक ही स्ट्रिंग-लेकिन intuitively समझने में आसान), संकलक केवल दो संदर्भों के साथ स्ट्रिंग का एक उदाहरण बना दिया जाएगा और।

वास्तव में, संकलक भी आगे जा सकते हैं: 'ab' + 'c' अनुकूलक, जो मामले में यह एक ही मॉड्यूल में एक 'abc' निरंतर के साथ एक साथ तह किया जा सकता द्वारा 'abc' में बदला जा सकता।

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


तो , प्रोग्रामर के रूप में आप इसके बारे में क्या करना चाहिए?

अच्छा ... कुछ भी नहीं। यदि आपके दो अपरिवर्तनीय मूल्य समान हैं तो आपके पास देखभाल करने का कोई कारण नहीं है। यदि आप जानना चाहते हैं कि a == b के बजाय आप a is b का उपयोग कब कर सकते हैं, तो आप गलत सवाल पूछ रहे हैं। अधिक पठनीय तुलना के लिए सिंगलटन मूल्यों के x is None तरह

  • : बस हमेशा a == b दो मामलों को छोड़कर का उपयोग करें।
  • परिवर्तनीय मूल्यों के लिए, जब आपको यह जानने की आवश्यकता है कि x पर उत्परिवर्तन y को प्रभावित करेगा या नहीं।
3

is और is not पायथन में दो पहचान ऑपरेटर हैं। is ऑपरेटर चर के मानों की तुलना नहीं करता है, लेकिन चर की पहचान की तुलना करता है। इस पर विचार करें:

>>> a = [1,2,3] 
>>> b = [1,2,3] 
>>> hex(id(a)) 
'0x1079b1440' 
>>> hex(id(b)) 
'0x107960878' 
>>> a is b 
False 
>>> a == b 
True 
>>> 

ऊपर के उदाहरण आपको पता चलता है कि पहचान (यह भी CPython में स्मृति पता हो सकता है) a और b दोनों के लिए अलग है (भले ही उनके मूल्यों ही कर रहे हैं)। यही कारण है कि जब आप a is b कहते हैं तो यह दोनों ऑपरेटरों की पहचान में मेल नहीं खाती है। हालांकि जब आप a == b कहते हैं, तो यह सच हो जाता है क्योंकि == ऑपरेशन केवल सत्यापित करता है कि दोनों ऑपरेटरों के पास समान मूल्य है।

दिलचस्प उदाहरण (अतिरिक्त ग्रेड के लिए):

>>> del a 
>>> del b 
>>> a = 132 
>>> b = 132 
>>> hex(id(a)) 
'0x7faa2b609738' 
>>> hex(id(b)) 
'0x7faa2b609738' 
>>> a is b 
True 
>>> a == b 
True 
>>> 

उपरोक्त उदाहरण में, भले ही a और b दो अलग चर हैं, a is bTrue लौट आए। ऐसा इसलिए है क्योंकि a का प्रकार int है जो एक अपरिवर्तनीय वस्तु है। तो पायथन (मुझे स्मृति को बचाने का अनुमान है) उसी वस्तु को आवंटित किया गया था जब यह उसी मूल्य के साथ बनाया गया था b पर। तो इस मामले में, मिलान किए गए चर की पहचान और a is bTrue हो गई।

यह सब अपरिवर्तनीय वस्तुओं के लिए लागू होंगे:

>>> del a 
>>> del b 
>>> a = "asd" 
>>> b = "asd" 
>>> hex(id(a)) 
'0x1079b05a8' 
>>> hex(id(b)) 
'0x1079b05a8' 
>>> a is b 
True 
>>> a == b 
True 
>>> 

आशा है कि मदद करता है।

+0

यह वास्तविक उदाहरण है। विस्तृत जानकारी के लिए धन्यवाद। – Haranadh

+0

लेकिन कोशिश करें ए = 123456789 बी = 123456789 – user2183078

3

x is y वस्तुओं की पहचान की तुलना में id(x) == id(y) के समान है।

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