क्या "==" और "है" के बीच अंतर है?


630

मेरा Google-fu मुझे विफल कर चुका है।

पायथन में, समानता के लिए निम्नलिखित दो परीक्षण समान हैं?

n = 5
# Test one.
if n == 5:
    print 'Yay!'

# Test two.
if n is 5:
    print 'Yay!'

क्या यह उन वस्तुओं के लिए सही है जहाँ आप उदाहरणों (एक listकहा) की तुलना करेंगे ?

ठीक है, तो इस तरह के जवाब मेरे सवाल:

L = []
L.append(1)
if L == [1]:
    print 'Yay!'
# Holds true, but...

if L is [1]:
    print 'Yay!'
# Doesn't.

तो ==परीक्षण मूल्य जहां isपरीक्षण देखने के लिए कि क्या वे एक ही वस्तु हैं?

जवाबों:


928

isTrueयदि दो चर एक ही वस्तु की ओर इंगित करते हैं, ==तो वापस आएंगे , यदि चर द्वारा संदर्भित वस्तुएं समान हैं।

>>> a = [1, 2, 3]
>>> b = a
>>> b is a 
True
>>> b == a
True

# Make a new copy of list `a` via the slice operator, 
# and assign it to variable `b`
>>> b = a[:] 
>>> b is a
False
>>> b == a
True

आपके मामले में, दूसरा परीक्षण केवल इसलिए काम करता है क्योंकि पायथन छोटी पूर्णांक वस्तुओं को कैश करता है, जो एक कार्यान्वयन विवरण है। बड़े पूर्णांकों के लिए, यह काम नहीं करता है:

>>> 1000 is 10**3
False
>>> 1000 == 10**3
True

स्ट्रिंग शाब्दिकों के लिए भी यही सही है:

>>> "a" is "a"
True
>>> "aa" is "a" * 2
True
>>> x = "a"
>>> "aa" is x * 2
False
>>> "aa" is intern(x*2)
True

कृपया इस प्रश्न को भी देखें।


2
मैंने पाया कि: echo 'import sys;tt=sys.argv[1];print(tt is "foo", tt == "foo", id(tt)==id("foo"))'| python3 - fooआउटपुट False True False:।
आहिगो जूल 23'18

आपने मुझे b = a[:]स्लाइस ऑपरेटर सूची प्रतिलिपि भाग के साथ खो दिया है , इसलिए मैंने आपके उत्तर को एक टिप्पणी के लिए संपादित किया है। ऐसा लगता है कि मैं लागू होने से पहले मेरे संपादन की समीक्षा नहीं करने के लिए दहलीज पर पहुंच गया था, इसलिए उम्मीद है कि यह आपके साथ अच्छा होगा। इसके बावजूद, यहां उन सूचियों की प्रतिलिपि बनाने का एक उपयोगी संदर्भ है जो मुझे आई थीं और यह पता लगाने के लिए संदर्भ था कि आप क्या कर रहे थे: stackoverflow.com/a/2612815/4561887
गेब्रियल स्टेपल्स

अंतर प्रदर्शित करने का एक अन्य तरीका विभिन्न प्रकारों की वस्तुओं की तुलना करना है, जो निश्चित रूप से, एक ही वस्तु नहीं हो सकती है, लेकिन फिर भी उपयोग करते समय बराबर की तुलना करें ==। तो 5.0उदाहरण के लिए, एक चल बिन्दु मूल्य है, जबकि है 5एक पूर्णांक है। लेकिन 5.0 == 5फिर भी लौटेंगे Trueक्योंकि वे उसी मूल्य का प्रतिनिधित्व करते हैं। प्रदर्शन और बतख-टाइपिंग के संदर्भ में, isहमेशा दुभाषिया द्वारा ऑपरेटर की मेमोरी एड्रेसेस की तुलना करके परीक्षण किया जाता है, जबकि इसके साथ ==यह तय करना है कि क्या यह किसी और चीज़ के बराबर परिभाषित करता है।
बछसौ

3
1000 is 10**3पायथन 3.7 में ट्रू का मूल्यांकन 10 से 3 ** प्रकार है int। लेकिन 1000 is 1e31e3 के प्रकार के बाद से गलत का मूल्यांकन करता है float
अहमद फ़सीह

@AhmedFasih 1000 is 10**3कार्यान्वयन निर्भर है या नहीं, यह सच है, और संकलक पर निर्भर करता है कि वह अभिव्यक्ति का पूर्व-मूल्यांकन कर रहा है 10**3x=10; 1000 is x**3का मूल्यांकन करता है False
शेफनर

312

उपयोग करने के लिए ==या आपको यह बताने के लिए अंगूठे का एक सरल नियम है is

  • ==के लिए है मूल्य समानता । इसका उपयोग तब करें जब आप जानना चाहें कि क्या दो वस्तुओं का समान मूल्य है।
  • isके लिए है संदर्भ समानता । इसका उपयोग तब करें जब आप जानना चाहें कि दो संदर्भ एक ही वस्तु को संदर्भित करते हैं।

सामान्य तौर पर, जब आप किसी चीज़ की तुलना साधारण प्रकार से कर रहे होते हैं , तो आप आमतौर पर मूल्य समानता की जाँच कर रहे होते हैं , इसलिए आपको इसका उपयोग करना चाहिए ==। उदाहरण के लिए, आपके उदाहरण का उद्देश्य संभवतः यह जांचना है कि क्या x का मान 2 ( ==) के बराबर है , न कि क्या xशाब्दिक रूप से 2 के समान वस्तु का उल्लेख है।


कुछ और ध्यान दें: सीपीथॉन संदर्भ कार्यान्वयन के काम करने के तरीके के कारण, आपको अप्रत्याशित और असंगत परिणाम मिलेंगे यदि आप गलती isसे पूर्णांक पर संदर्भ समानता के लिए तुलना करने के लिए उपयोग करते हैं:

>>> a = 500
>>> b = 500
>>> a == b
True
>>> a is b
False

यह बहुत अधिक है कि हम क्या उम्मीद करते हैं: aऔर bएक ही मूल्य है, लेकिन अलग-अलग संस्थाएं हैं। लेकिन इससे क्या?

>>> c = 200
>>> d = 200
>>> c == d
True
>>> c is d
True

यह पहले के परिणाम से असंगत है। यहाँ क्या चल रहा है? यह प्रदर्शन के कारणों के लिए सिंगलटन उदाहरणों के रूप में रेंज -5 में पिथन कैश्स पूर्णांक वस्तुओं के संदर्भ कार्यान्वयन को दर्शाता है। यहाँ एक उदाहरण यह प्रदर्शित करता है:

>>> for i in range(250, 260): a = i; print "%i: %s" % (i, a is int(str(i)));
... 
250: True
251: True
252: True
253: True
254: True
255: True
256: True
257: False
258: False
259: False

यह उपयोग नहीं करने का एक और स्पष्ट कारण है is: व्यवहार को कार्यान्वयन के लिए छोड़ दिया जाता है जब आप गलती से इसे मूल्य समानता के लिए उपयोग कर रहे हैं।


साथ का पहला उदाहरण के संबंध a=500और b=500, बस का कहना चाहते थे, तो आपके द्वारा सेट किए aऔर b[-5, 256] के बीच एक interger, करने के लिए a is bवास्तव में रिटर्न True। यहाँ अधिक जानकारी: stackoverflow.com/q/306313/7571052
ऐशकेचम

1
@AsheKetchum, हाँ, ध्यान दें कि मैंने लिखा था "यह प्रदर्शन कारणों के लिए सिंगलटन इंस्टेंस के रूप में रेंज -5 में पाइथन कैश के पूर्णांक वस्तुओं के संदर्भ कार्यान्वयन को दर्शाता है।"
जॉन फेमिनाला

34

==यदि मान समान हैं, तो isयह निर्धारित करता है कि क्या वे समान समान वस्तु हैं।


32

क्या पायथन में ==और बीच में कोई अंतर है is?

हां, उनमें बहुत महत्वपूर्ण अंतर है।

==: समानता की जाँच करें - शब्दार्थ यह है कि समतुल्य वस्तुएँ (जो कि समान वस्तु नहीं हैं) समान रूप से परीक्षण करेंगी। जैसा कि प्रलेखन कहता है :

ऑपरेटर <,>, ==,> =, <=, और = दो वस्तुओं के मूल्यों की तुलना करते हैं।

is: पहचान के लिए जाँच - अर्थ विज्ञान हैं कि वस्तु (के रूप में स्मृति में आयोजित) है वस्तु। फिर, प्रलेखन कहता है :

ऑब्जेक्ट आइडेंटिफ़िकेशन के लिए ऑपरेटर isऔर is notटेस्ट: x is yसच है अगर और केवल अगर xऔर yएक ही ऑब्जेक्ट हैं। id()फ़ंक्शन का उपयोग करके ऑब्जेक्ट की पहचान निर्धारित की जाती है। x is not yउलटा सत्य मूल्य देता है।

इस प्रकार, पहचान की जांच वस्तुओं की आईडी की समानता के लिए जाँच के समान है। अर्थात्,

a is b

के समान है:

id(a) == id(b)

idबिल्टइन फ़ंक्शन कहाँ है जो एक पूर्णांक देता है जो "एक साथ मौजूदा वस्तुओं के बीच अद्वितीय होने की गारंटी है" (देखें help(id)) और कहाँ aऔर bकिसी भी मनमाना ऑब्जेक्ट हैं।

अन्य उपयोग दिशाएँ

आपको उनकी तुलना उनके शब्दार्थ के लिए करनी चाहिए। isपहचान ==की जांच करने और समानता की जांच करने के लिए उपयोग करें ।

तो सामान्य तौर पर, हम उपयोग करते हैं is पहचान के लिए जांच करते हैं। यह आमतौर पर तब उपयोगी होता है जब हम एक ऐसी वस्तु की जाँच कर रहे होते हैं जिसे केवल एक बार मेमोरी में मौजूद होना चाहिए, जिसे प्रलेखन में "सिंगलटन" कहा जाता है।

isशामिल मामलों के लिए उपयोग करें :

  • None
  • Enum मान (Enum मॉड्यूल से Enums का उपयोग करते समय)
  • आमतौर पर मॉड्यूल
  • आमतौर पर कक्षा की वस्तुओं को वर्ग परिभाषाओं के परिणामस्वरूप
  • आमतौर पर फ़ंक्शन परिभाषाओं से उत्पन्न होने वाली वस्तुएं
  • कुछ और जो केवल एक बार स्मृति में मौजूद होना चाहिए (सभी एकल, आम तौर पर)
  • एक विशिष्ट वस्तु जिसे आप पहचान द्वारा चाहते हैं

==शामिल करने के लिए सामान्य उपयोग के मामले :

  • पूर्णांकों सहित संख्याएँ
  • तार
  • सूचियों
  • सेट
  • शब्दकोशों
  • कस्टम म्यूटेबल ऑब्जेक्ट्स
  • अन्य बिलियन अपरिवर्तनीय वस्तुओं, ज्यादातर मामलों में

सामान्य उपयोग का मामला, फिर, के लिए ==, वह वस्तु है जो आप चाहते हैं कि एक ही वस्तु न हो , इसके बजाय यह एक समतुल्य हो सकता है एक

पीईपी 8 दिशा

पीईपी 8, मानक पुस्तकालय के लिए आधिकारिक पायथन शैली गाइड में निम्नलिखित दो मामलोंis का भी उल्लेख किया गया है :

Noneहमेशा की तरह एकल ऑपरेटरों के साथ तुलना की जानी चाहिए isया is notकभी भी समानता ऑपरेटरों के साथ नहीं होनी चाहिए ।

इसके अलावा, लिखने से सावधान रहें if xजब आप वास्तव में मतलब रखते हैं if x is not None- उदाहरण के लिए परीक्षण करते समय कि क्या एक चर या तर्क जो डिफॉल्ट करता है None वह कुछ अन्य मूल्य पर सेट किया गया था। दूसरे मूल्य में एक प्रकार (जैसे कंटेनर) हो सकता है जो बूलियन संदर्भ में गलत हो सकता है!

पहचान से समानता का हवाला देते हुए

अगर isसच है, तो समानता आमतौर पर हो सकती है बांझ हो सकती है - तार्किक रूप से, यदि कोई वस्तु स्वयं है, तो उसे स्वयं के बराबर परीक्षण करना चाहिए।

ज्यादातर मामलों में यह तर्क सही है, लेकिन यह __eq__विशेष पद्धति के कार्यान्वयन पर निर्भर करता है । जैसा कि डॉक्स कहते हैं,

समानता तुलना ( ==और !=) के लिए डिफ़ॉल्ट व्यवहार वस्तुओं की पहचान पर आधारित है। इसलिए, समान पहचान वाले उदाहरणों की समानता की तुलना समानता में होती है, और विभिन्न पहचानों वाले उदाहरणों की समानता तुलना में असमानता होती है। इस डिफ़ॉल्ट व्यवहार के लिए एक प्रेरणा यह इच्छा है कि सभी वस्तुओं को प्रतिवर्त होना चाहिए (अर्थात x का अर्थ है x == y)।

और संगति के हितों में, अनुशंसा करता है:

समानता की तुलना प्रतिवर्त होनी चाहिए। दूसरे शब्दों में, समान वस्तुओं की तुलना बराबर होनी चाहिए:

x is y का तात्पर्य x == y

हम देख सकते हैं कि यह कस्टम ऑब्जेक्ट्स के लिए डिफ़ॉल्ट व्यवहार है:

>>> class Object(object): pass
>>> obj = Object()
>>> obj2 = Object()
>>> obj == obj, obj is obj
(True, True)
>>> obj == obj2, obj is obj2
(False, False)

गर्भनिरोधक भी आम तौर पर सच है - अगर किसी चीज़ के परीक्षण के बराबर नहीं है, तो आप आमतौर पर अनुमान लगा सकते हैं कि वे समान वस्तु नहीं हैं।

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

एक अपवाद

एक उल्लेखनीय अपवाद है nan- यह हमेशा स्वयं के बराबर नहीं के रूप में परीक्षण करता है:

>>> nan = float('nan')
>>> nan
nan
>>> nan is nan
True
>>> nan == nan           # !!!!!
False

पहचान के लिए जाँच करना समानता के लिए जाँच करने की तुलना में बहुत तेज़ जाँच हो सकती है (जिसके लिए सदस्यों की पुनरावर्ती जाँच की आवश्यकता हो सकती है)।

लेकिन इसे समानता के लिए प्रतिस्थापित नहीं किया जा सकता है जहाँ आपको एक से अधिक ऑब्जेक्ट समान के रूप में मिल सकते हैं।

ध्यान दें कि सूचियों और टुपल्स की समानता की तुलना यह मान लेगी कि वस्तुओं की पहचान बराबर है (क्योंकि यह एक तेज़ जाँच है)। यह विरोधाभास पैदा कर सकता है यदि तर्क असंगत है - जैसा कि यह है nan:

>>> [nan] == [nan]
True
>>> (nan,) == (nan,)
True

एक सावधानी कथा:

प्रश्न isपूर्णांक की तुलना करने के लिए उपयोग करने का प्रयास कर रहा है । आपको यह नहीं समझना चाहिए कि पूर्णांक का एक उदाहरण उसी उदाहरण के समान है जिसे किसी अन्य संदर्भ द्वारा प्राप्त किया गया है। यह कहानी बताती है कि क्यों।

एक टिप्पणीकार के पास कोड था जो इस तथ्य पर निर्भर करता था कि छोटे पूर्णांक (-5 से 256 समावेशी) समानता के लिए जांचने के बजाय पायथन में एकल हैं।

वाह, यह कुछ कपटी कीड़े पैदा कर सकता है। मेरे पास कुछ कोड थे जो अगर a, b है, जो कि मैं चाहता था के रूप में काम करता था क्योंकि a और b आमतौर पर छोटी संख्या है। बग केवल उत्पादन के छह महीने बाद आज ही हुआ है, क्योंकि ए और बी अंत में काफी बड़े थे जिन्हें कैश नहीं किया गया था। - gwg

इसने विकास में काम किया। यह कुछ unittests पारित हो सकता है।

और इसने उत्पादन में काम किया - जब तक कोड एक पूर्णांक 256 से बड़ा नहीं हो जाता, तब तक यह उत्पादन में विफल रहा।

यह एक उत्पादन विफलता है जिसे कोड समीक्षा या संभवतः एक स्टाइल-चेकर के साथ पकड़ा जा सकता था।

मुझे जोर देने दें: पूर्णांक की तुलना करने के लिए उपयोग न करें is


"उपयोग न करें" एक अच्छा नियम भी होगा। मुहावरेदार is Noneएक अपवाद है, लेकिन यह कहा == Noneभी काम करता है ...
जीन फ़्राँस्वा Fabre

@ जीन-फ्रांस्वा फ़ेबरे एक और अपवाद: आधिकारिक दस्तावेज एस की isतुलना करने के लिए उपयोग करने की सलाह देता है Enum
आर्थर

@Arthur मैं उपयोग के मामलों की एक सूची को शामिल किया है ...
हारून हॉल

19

बीच क्या अंतर है isऔर ==?

==और isअलग तुलना कर रहे हैं! जैसा कि दूसरों ने पहले ही कहा है:

  • == वस्तुओं के मूल्यों की तुलना करता है।
  • is वस्तुओं के संदर्भों की तुलना करता है।

पायथन के नाम में वस्तुओं का उल्लेख है, उदाहरण के लिए इस मामले में value1और उदाहरण के लिए मान को संग्रहीत करते हुए value2देखें :int1000

value1 = 1000
value2 = value1

यहाँ छवि विवरण दर्ज करें

क्योंकि value2उसी वस्तु को संदर्भित करता है isऔर ==देगा True:

>>> value1 == value2
True
>>> value1 is value2
True

निम्नलिखित उदाहरण में नाम value1और value2विभिन्न intउदाहरणों को देखें , भले ही दोनों एक ही पूर्णांक को संग्रहीत करें:

>>> value1 = 1000
>>> value2 = 1000

यहाँ छवि विवरण दर्ज करें

क्योंकि एक ही मूल्य (पूर्णांक) संग्रहीत किया जाता ==है True, इसीलिए इसे अक्सर "मूल्य तुलना" कहा जाता है। हालाँकि ये isवापस आ जाएंगे Falseक्योंकि ये अलग-अलग वस्तुएं हैं:

>>> value1 == value2
True
>>> value1 is value2
False

कब कौन सा उपयोग करें?

आम तौर isपर एक बहुत तेजी से तुलना है। इसलिए CPython कैश (या शायद reuses होगा बेहतर शब्द) छोटे पूर्णांक, कुछ तार, आदि जैसे कुछ वस्तुओं लेकिन इस के रूप में व्यवहार किया जाना चाहिए कार्यान्वयन विस्तार (भले ही संभावना न हो) चेतावनी के बिना किसी भी बिंदु पर बदल सकता है।

आपको केवल तभी उपयोगis करना चाहिए जब आप:

  • जांचना चाहते हैं कि क्या दो वस्तुएं वास्तव में एक ही वस्तु हैं (केवल "मान" नहीं)। एक उदाहरण हो सकता है यदि आप एक सिंगलटन ऑब्जेक्ट को स्थिर के रूप में उपयोग करते हैं।
  • मान की तुलना पायथन स्थिरांक से करना चाहते हैं । पायथन में स्थिरांक हैं:

    • None
    • True1
    • False1
    • NotImplemented
    • Ellipsis
    • __debug__
    • वर्गों (उदाहरण के लिए int is intया int is float)
    • अंतर्निहित मॉड्यूल या 3 पार्टी मॉड्यूल में अतिरिक्त स्थिरांक हो सकते हैं। np.ma.maskedNumPy मॉड्यूल से उदाहरण के लिए )

में हर दूसरे मामले का उपयोग करना चाहिए== समानता के लिए जाँच करने के लिए।

क्या मैं व्यवहार को अनुकूलित कर सकता हूं?

इसका कुछ पहलू यह है ==कि पहले से ही अन्य उत्तरों में इसका उल्लेख नहीं किया गया है: यह पायथन "डेटा मॉडल" का हिस्सा है । इसका मतलब है कि इसका व्यवहार __eq__विधि का उपयोग करके अनुकूलित किया जा सकता है । उदाहरण के लिए:

class MyClass(object):
    def __init__(self, val):
        self._value = val

    def __eq__(self, other):
        print('__eq__ method called')
        try:
            return self._value == other._value
        except AttributeError:
            raise TypeError('Cannot compare {0} to objects of type {1}'
                            .format(type(self), type(other)))

यह वर्णन करने के लिए केवल एक कृत्रिम उदाहरण है कि विधि वास्तव में कहा जाता है:

>>> MyClass(10) == MyClass(10)
__eq__ method called
True

ध्यान दें कि डिफ़ॉल्ट रूप से (यदि कोई अन्य कार्यान्वयन __eq__वर्ग या सुपरक्लासेस में नहीं पाया जा सकता है) __eq__का उपयोग करता है is:

class AClass(object):
    def __init__(self, value):
        self._value = value

>>> a = AClass(10)
>>> b = AClass(10)
>>> a == b
False
>>> a == a

इसलिए इसे लागू करना वास्तव में महत्वपूर्ण है __eq__यदि आप कस्टम कक्षाओं के लिए केवल संदर्भ-तुलना की तुलना में "अधिक" चाहते हैं तो करना !

दूसरी ओर आप isचेक को कस्टमाइज़ नहीं कर सकते हैं । यह हमेशा की तुलना करेंगे सिर्फ अगर आप एक ही संदर्भ है।

क्या ये तुलना हमेशा एक बूलियन लौटाएगी?

क्योंकि __eq__फिर से लागू किया जा सकता है या ओवरराइड किया जा सकता है, यह वापस लौटने Trueया करने के लिए सीमित नहीं है False। यह कुछ भी वापस कर सकता है (लेकिन ज्यादातर मामलों में यह एक बूलियन लौटना चाहिए!)।

NumPy सरणियों के साथ उदाहरण के लिए, ==एक सरणी लौटाएगा:

>>> import numpy as np
>>> np.arange(10) == 2
array([False, False,  True, False, False, False, False, False, False, False], dtype=bool)

लेकिन isचेक हमेशा वापस आ जाएगा Trueया False!


1 टिप्पणी में उल्लेख किया हारून हॉल के रूप में:

आम तौर पर आप किसी भी ऐसा नहीं करना चाहिए is Trueया is Falseचेक के कारण एक सामान्य रूप से एक संदर्भ है कि परोक्ष धर्मान्तरित में इन "चेक" का उपयोग करता हालत (एक में, उदाहरण के लिए एक बूलियन के ifबयान)। तो is Trueतुलना करना और निहित बूलियन कास्ट बूलियन कास्ट करने की तुलना में अधिक काम कर रहा है - और आप अपने आप को बूलियन तक सीमित कर लेते हैं (जिसे पाइथोनिक नहीं माना जाता है)।

PEP8 उल्लेख की तरह:

बूलियन मूल्यों की तुलना Trueया Falseउपयोग न करें ==

Yes:   if greeting:
No:    if greeting == True:
Worse: if greeting is True:

2
मैं "स्थिरांक" की तुलना करने के लिए आपके दावे पर असहमत होने जा रहा हूं is- ऐसे नाम जो बूलियंस को इंगित करते हैं, उन्हें बूलियन संदर्भ के साथ जांचना चाहिए - जैसे if __debug__:या if not __debug__:। आपको कभी भी if __debug__ is True:या नहीं करना चाहिए if __debug__ == True:- आगे, एक स्थिरांक केवल एक निरंतर अर्थ मूल्य है, एक सिंगलटन नहीं है, इसलिए isउस मामले में जांच करना शब्दार्थ रूप से सही नहीं है। मैं आपको अपने दावे का समर्थन करने के लिए एक स्रोत खोजने के लिए चुनौती देता हूं - मुझे नहीं लगता कि आप एक पाएंगे।
हारून हॉल

@AaronHall आपको क्या लगता है कि स्थिरांक एकल नहीं हैं? ध्यान दें कि केवल None, True, Falseऔर __debug__क्या आप, "निरंतर अर्थ मूल्य" कहेंगे क्योंकि वे पुन: असाइन नहीं किया जा सकता है। लेकिन ये सभी सिंगल हैं।
MSeifert

PEP 8 - Ctrl-F पढ़ें और शब्द को देखें, "बदतर"। - आप कर रहे हैं unittesting आप उपयोग करेंगे तो self.assertTrue
हारून हॉल

@AaronHall कुछ परिस्थितियों में आपको वास्तव में is Trueया if Falseचेक की आवश्यकता होती है (लेकिन हाँ, ये बहुत दुर्लभ हैं - लेकिन यदि आप उन्हें करते हैं तो आप उनका उपयोग कर सकते हैं is)। इसलिए भी CPython कभी-कभी उनका उपयोग करता है (उदाहरण के लिए यहाँ या यहाँ )
MSeifert

19

वे पूरी तरह से अलग हैंisवस्तु पहचान के लिए जाँच, जबकि ==समानता के लिए जाँच (एक धारणा जो दो ऑपरेंड के प्रकारों पर निर्भर करती है)।

यह केवल एक भाग्यशाली संयोग है कि " is" छोटे पूर्णांक (जैसे 5 == 4 + 1) के साथ सही ढंग से काम करता है। ऐसा इसलिए है क्योंकि CPython पूर्णांक (-5 से 256) में पूर्णांक के संग्रहण को एकल बनाकर उनका अनुकूलन करता है । यह व्यवहार पूरी तरह से कार्यान्वयन-निर्भर है और सभी प्रकार के मामूली परिवर्तनकारी कार्यों के तहत संरक्षित होने की गारंटी नहीं है।

उदाहरण के लिए, पायथन 3.5 भी छोटे तारों को एकल बनाता है, लेकिन उनके फिसलने से यह व्यवहार बाधित होता है:

>>> "foo" + "bar" == "foobar"
True
>>> "foo" + "bar" is "foobar"
True
>>> "foo"[:] + "bar" == "foobar"
True
>>> "foo"[:] + "bar" is "foobar"
False

10

https://docs.python.org/library/stdtypes.html#comparisons

is==समानता के लिए पहचान परीक्षणों के लिए परीक्षण

प्रत्येक (छोटे) पूर्णांक मान को एकल मान पर मैप किया जाता है, इसलिए प्रत्येक 3 समान और समान है। यह एक कार्यान्वयन विवरण है, हालांकि भाषा की युक्ति का हिस्सा नहीं है


6

आपका उत्तर सही है। isऑपरेटर दो वस्तुओं की पहचान है। ==ऑपरेटर दो वस्तुओं के मूल्यों तुलना करती है।

एक वस्तु की पहचान कभी नहीं बदल जाती है क्योंकि इसे बनाया गया है; आप इसे स्मृति में ऑब्जेक्ट के पते के रूप में सोच सकते हैं।

आप एक __cmp__विधि या एक समृद्ध तुलना विधि की तरह परिभाषित करके वस्तु मूल्यों के तुलनात्मक व्यवहार को नियंत्रित कर सकते हैं __eq__


4

स्टैक ओवरफ्लो प्रश्न पर एक नज़र है पायथन का "है" ऑपरेटर पूर्णांक के साथ अप्रत्याशित व्यवहार करता है

जो चीज ज्यादातर उबलती है, वह यह है कि " is" यह देखने के लिए जांचता है कि क्या वे एक ही वस्तु हैं, न कि एक दूसरे के बराबर (256 से नीचे की संख्या एक विशेष मामला है)।


3

संक्षेप में, isजाँचता है कि दो संदर्भ एक ही वस्तु को इंगित करते हैं या नहीं। ==जाँचता है कि दो वस्तुओं का समान मूल्य है या नहीं।

a=[1,2,3]
b=a        #a and b point to the same object
c=list(a)  #c points to different object 

if a==b:
    print('#')   #output:#
if a is b:
    print('##')  #output:## 
if a==c:
    print('###') #output:## 
if a is c:
    print('####') #no output as c and a point to different object 

2

जैसा कि जॉन फेमिनाला ने कहा, ज्यादातर समय आप == और! = का उपयोग करेंगे क्योंकि आपका उद्देश्य मूल्यों की तुलना करना है। मैं बस यह बताना चाहूंगा कि आप बाकी समय क्या करेंगे:

कोई नहीं है केवल एक और NoType का कोई उदाहरण है, कोई नहीं एक सिंगलटन है। नतीजतन foo == Noneऔर foo is Noneइसका मतलब वही है। हालांकि isपरीक्षण तेज है और पाइथोनिक सम्मेलन का उपयोग करना है foo is None

यदि आप कचरा संग्रह के बारे में कुछ आत्मनिरीक्षण या मैकिंग कर रहे हैं या जाँच कर रहे हैं कि क्या आपका कस्टम-निर्मित स्ट्रिंग इंटर्निंग गैजेट काम कर रहा है या इस तरह का है, तो संभवतः आपके लिए उपयोग-मामला fooहै bar

सच और गलत भी (अब) एकल हैं, लेकिन इसके लिए कोई उपयोग-मामला foo == Trueनहीं है और इसके लिए कोई उपयोग मामला नहीं है foo is True


2

उनमें से ज्यादातर ने पहले ही बिंदु पर जवाब दिया। बस एक अतिरिक्त नोट के रूप में (मेरी समझ और प्रयोग पर आधारित है लेकिन एक प्रलेखित स्रोत से नहीं), कथन

== यदि चर द्वारा संदर्भित ऑब्जेक्ट बराबर हैं

उपरोक्त उत्तरों के रूप में पढ़ा जाना चाहिए

== यदि चर द्वारा संदर्भित ऑब्जेक्ट समान हैं और समान प्रकार / वर्ग से संबंधित ऑब्जेक्ट हैं

। मैं नीचे दिए गए परीक्षण के आधार पर इस निष्कर्ष पर पहुंचा:

list1 = [1,2,3,4]
tuple1 = (1,2,3,4)

print(list1)
print(tuple1)
print(id(list1))
print(id(tuple1))

print(list1 == tuple1)
print(list1 is tuple1)

यहां सूची और टपल की सामग्री समान है लेकिन प्रकार / वर्ग भिन्न हैं।


2

अजगर के बीच अंतर और बराबर (==) है

हो सकता है कि ऑपरेटर समान ऑपरेटर के समान हो, लेकिन वे समान नहीं हैं।

यह जाँचता है कि क्या दोनों चर एक ही वस्तु की ओर इशारा करते हैं जबकि == दो चर के लिए मान समान होने पर चेक की जाँच करते हैं।

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

यहाँ समानता और अंतर को प्रदर्शित करने के लिए एक उदाहरण है।

>>> a = b = [1,2,3]
>>> c = [1,2,3]
>>> a == b
True
>>> a == c
True
>>> a is b
True
>>> a is c
False
>>> a = [1,2,3]
>>> b = [1,2]
>>> a == b
False
>>> a is b
False
>>> del a[2]
>>> a == b
True
>>> a is b
False
Tip: Avoid using is operator for immutable types such as strings and numbers, the result is unpredictable.

1
कृपया केवल दूसरे स्रोत से आपके द्वारा उद्धृत पाठ के लिए ब्लॉक उद्धरण का उपयोग करें, जिस बिंदु पर आपको रोपण शामिल होना चाहिए (देखें stackoverflow.com/help/referencing )। यदि यह आपका अपना पाठ है, तो कृपया ब्लॉक उद्धरण हटा दें।
मार्टिन पीटर्स

1

इस पोस्ट के जवाब के विवरण में सवाल में अन्य लोगों के रूप में, मैं होगा पर जोर मुख्य रूप से के बीच तुलना isऔर == तार के लिए जो अलग परिणाम दे सकता है और मैं प्रोग्रामर से आग्रह करता हूं ध्यान से उन्हें इस्तेमाल करने होगा।

स्ट्रिंग तुलना के लिए, ==इसके बजाय उपयोग करना सुनिश्चित करें is:

str = 'hello'
if (str is 'hello'):
    print ('str is hello')
if (str == 'hello'):
    print ('str == hello')

बाहर:

str is hello
str == hello

लेकिन नीचे के उदाहरण में ==और isअलग परिणाम मिलेंगे:

str = 'hello sam'
    if (str is 'hello sam'):
        print ('str is hello sam')
    if (str == 'hello sam'):
        print ('str == hello sam')

बाहर:

str == hello sam

निष्कर्ष:

isतार के बीच तुलना करने के लिए सावधानी से उपयोग करें


रिक्त स्थान के साथ तार के लिए "" "" ऐसा काम क्यों करता है?
आकाश गुप्त

पिछले उत्तरों के अनुसार: ऐसा लगता है कि अजगर छोटे पूर्णांक और तारों पर कैशिंग करता है, जिसका अर्थ है कि यह इस कोड स्नैपशॉट में 'हैलो' स्ट्रिंग आवृत्तियों के लिए समान ऑब्जेक्ट संदर्भ का उपयोग करता है, जबकि यह इस तरह से 'हैलो सैम' के लिए कैशिंग को प्रीफ़ॉर्म नहीं करता है। 'हैलो' की तुलना में अपेक्षाकृत बड़ा (यानी यह 'हैलो सैम' स्ट्रिंग के विभिन्न संदर्भों का प्रबंधन करता है, और इसीलिए 'ऑपरेटर' बाद के उदाहरण में गलत है) कृपया मुझे सही करें अगर मैं गलत हूं
Rida Shamasneh
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.