Python में तुलना ऑपरेटर (जिसे Python का रिलेशनल ऑपरेटर भी कहते हैं) दो ऑपरेंड की वैल्यू देखता है और यह तय करता है कि comparison शर्त पूरी होती है या नहीं। शर्त पूरी होने पर यह बूलियन True लौटाता है, वरना False.
नीचे दी गई तालिका Python के सबसे आम तुलना ऑपरेटर दिखाती है:
| ऑपरेटर | काम | विवरण |
|---|---|---|
> |
"इससे बड़ा" |
a > b तब True है जब a की वैल्यू b से पूर्णतः बड़ी हो |
< |
"इससे छोटा" |
a < b तब True है जब a की वैल्यू b से पूर्णतः छोटी हो |
== |
"इसके बराबर" |
a == b तब True है जब a की वैल्यू b के पूर्णतः बराबर हो |
>= |
"इससे बड़ा या बराबर" |
a >= b तब True है जब वैल्यू में a > b हो या a == b हो |
<= |
"इससे छोटा या बराबर" |
a <= b तब True है जब वैल्यू में a < b हो या a == b हो |
!= |
"इसके बराबर नहीं" |
a != b तब True है जब a == b का नतीजा False हो |
is |
"पहचान" |
a is b तब True है जब और सिर्फ तभी a और b एक ही ऑब्जेक्ट हों |
is not |
"नकारात्मक पहचान" |
a is not b तब True है जब और सिर्फ तभी a और b एक ही ऑब्जेक्ट न हों |
in |
"समावेशन की जाँच" |
a in b तब True है जब a, b का सदस्य, उपसमुच्चय या एलिमेंट हो |
not in |
"नकारात्मक समावेशन की जाँच" |
a not in b तब True है जब a, b का सदस्य, उपसमुच्चय या एलिमेंट न हो |
इन सब की प्राथमिकता एक जैसी होती है (जो बूलियन ऑपरेशन से ऊँची है, लेकिन अंकगणितीय या बिटवाइज़ ऑपरेशन से नीची)।
अलग-अलग टाइप के ऑब्जेक्ट (संख्यात्मक टाइप को छोड़कर) डिफ़ॉल्ट रूप से कभी बराबर नहीं माने जाते।
किसी class के अलग-अलग इंस्टेंस भी तब तक बराबर नहीं माने जाएँगे, जब तक वह class ऐसे विशेष रिच कंपैरिज़न मेथड न बनाए जो object की डिफ़ॉल्ट तुलना का व्यवहार अपने हिसाब से बदल दें।
(बहुत) ज़्यादा विस्तार से जानने के लिए Python के डॉक्युमेंटेशन में वैल्यू तुलना देखिए।
संख्यात्मक टाइप (ज़्यादातर) इस टाइप-मिलान नियम के अपवाद हैं।
एक integer को float के बराबर माना जा सकता है (या एक octal को एक hexadecimal के बराबर), बशर्ते तुलना के लिए दोनों टाइप अपने आप रूपांतरित हो सकें।
बाकी संख्यात्मक टाइप (कॉम्प्लेक्स, दशमलव, भिन्न) के लिए तुलना ऑपरेटर वहाँ तक परिभाषित हैं जहाँ उनका मतलब बनता है (यानी जहाँ अपने आप रूपांतरण से नतीजा नहीं बदलता), लेकिन अगर तुलना के लिए अंदर के ऑब्जेक्ट ठीक से रूपांतरित न हो सकें, तो ये TypeError फेंकते हैं।
Python संख्या रूपांतरण के लिए कौन-कौन से नियम इस्तेमाल करता है, इसकी ज़्यादा जानकारी के लिए Python के डॉक्युमेंटेशन में अंकगणितीय रूपांतरण देखिए।
>>> import fractions
# A string cannot be converted to an int.
>>> 17 == '17'
False
# An int can be converted to float for comparison.
>>> 17 == 17.0
True
# The fraction 6/3 can be converted to the int 2
# The int 2 can be converted to 0b10 in binary.
>>> 6/3 == 0b10
True
# An int can be converted to a complex
# number with a 0 imaginary part.
>>> 17 == complex(17)
True
# The fraction 2/5 can be converted to the float 0.4
>>> 0.4 == 2/5
True
>>> complex(2/5, 1/2) == complex(0.4, 0.5)
True
किसी संख्या की NaN (जिसका मतलब है, संख्या नहीं) टाइप से कोई भी क्रम-तुलना False देती है।
Python में NaN की परिभाषा का एक उलझाने वाला असर यह है कि NaN कभी NaN के बराबर नहीं माना जाता।
अगर आप जानना चाहें कि Python में NaN को इस तरह क्यों परिभाषित किया गया, तो अंतरराष्ट्रीय मानक तय होने के आस-पास लिखी गई यह NaN पर Stack Overflow की पोस्ट दिलचस्प पढ़ाई है।
>>> x = float('NaN')
>>> 3 < x
False
>>> x < 3
False
# NaN never compares equal to NaN
>>> x == x
False
स्ट्रिंग (str) की तुलना शब्दकोशीय क्रम में होती है, और इसके लिए उनके अलग-अलग Unicode कोड पॉइंट इस्तेमाल होते हैं (यानी str के हर कोड पॉइंट को बिल्ट-इन फंक्शन ord() में देने पर जो नतीजा मिलता है, जो एक int लौटाता है)।
अगर दोनों स्ट्रिंग के सारे कोड पॉइंट मिलते हों और उसी क्रम में हों, तो दोनों स्ट्रिंग बराबर मानी जाती हैं।
यह तुलना 'जोड़ी-दर-जोड़ी' होती है - पहला-पहले से, दूसरा-दूसरे से, वगैरह।
Python 3.x में str और bytes को सीधे एक-दूसरे में बदला या तुलना नहीं किया जा सकता।
>>> 'Python' > 'Rust'
False
>>> 'Python' > 'JavaScript'
True
# Examples with Mandarin.
# hello < goodbye
>>> '你好' < '再见'
True
# ord() of first characters
>>> ord('你'), ord('再')
(20320, 20877)
# ord() of second characters
>>> ord('好'), ord('见')
(22909, 35265)
# And with Korean words.
# Pretty < beautiful.
>>> '예쁜' < '아름다운'
False
>>> ord('예'), ord('아')
(50696, 50500)
कंटेनर डेटा टाइप (lists, tuples, sets, dicts आदि) की तुलना भी शब्दकोशीय क्रम में होती है - अगर दोनों कंटेनर में एक ही डेटा और एक ही डेटा टाइप हों तो वे बराबर होते हैं (lists और tuples के मामले में क्रम भी एक ही होना चाहिए), वरना नहीं।
>>> [1, 2] == [1, 2]
True
# But if the data is not in the same order, they are not equal.
>>> [2, 1] == [1, 2]
False
# The same holds true for tuples
>>> (3,4,5) == (5,4,3)
False
# Length is also compared
>>> [1, 2] < [1, 2, 3]
True
# Comparing dicts
>>> {'name': 'John', 'age': 19} == {'name': 'John', 'age': 18}
False
>>> {'name': 'John', 'age': 19} == {'name': 'John', 'age': 19}
True
तुलना ऑपरेटरों को मनमाने ढंग से चेन किया जा सकता है।
ध्यान दीजिए कि किसी एक्सप्रेशन का मूल्यांकन left से right की ओर होता है।
जैसे x < y <= z, x < y and y <= z के बराबर है, बस फर्क यह है कि इसमें y का मूल्यांकन सिर्फ एक बार होता है।
दोनों ही स्थितियों में, जब x < y का नतीजा False निकलता है, तो z का मूल्यांकन बिल्कुल भी नहीं होता।
इसे अक्सर short-circuit evaluation कहा जाता है - अगर एक्सप्रेशन का सत्य मान पहले ही तय हो चुका हो, तो मूल्यांकन वहीं रुक जाता है।
Short circuiting कई बूलियन ऑपरेटर और फंक्शन करते हैं, और Python में तुलना की चेनिंग भी इसे सपोर्ट करती है।
कई दूसरी प्रोग्रामिंग भाषाओं (C, C++, C# और Java आदि) के उलट, Python में a < b < c जैसे चेन किए गए एक्सप्रेशन गणितीय व्याख्या और प्राथमिकता के पारंपरिक हिसाब से चलते हैं।
>>> x = 2
>>> y = 5
>>> z = 10
>>> x < y < z
True
>>> x < y > z
False
>>> x > y < z
False
is और is not ऑपरेटर ऑब्जेक्ट की वैल्यू के बजाय ऑब्जेक्ट की पहचान की जाँच करते हैं।
किसी ऑब्जेक्ट की पहचान बनने के बाद कभी नहीं बदलती, और उसे id() फंक्शन से पता किया जा सकता है।
<apple> is <orange> तब True देता है जब और सिर्फ तभी id(<apple>) == id(<orange>) हो।
<apple> is not <orange> इसका उल्टा नतीजा देता है।
सिंगलटन होने के कारण None और NotImplemented की तुलना हमेशा is और is not से ही करनी चाहिए।
इस परंपरा की ज़्यादा जानकारी के लिए Python के रेफरेंस डॉक्स में वैल्यू तुलना और PEP8 देखिए।
# A list of favorite numbers.
>>> my_fav_numbers = [1, 2, 3]
>>> your_fav_numbers = my_fav_numbers
>>> my_fav_numbers is your_fav_numbers
True
# The returned id will differ by system and Python version.
>>> id(my_fav_numbers)
4517478208
# your_fav_numbers is only an alias pointing to the original my_fav_numbers object.
# Assigning a new name does not create a new object.
>>> id(your_fav_numbers)
4517478208
>>> my_fav_numbers is not your_fav_numbers
False
>>> my_fav_numbers is not None
True
>>> my_fav_numbers is NotImplemented
False
in और not in ऑपरेटर सदस्यता की जाँच करते हैं।
<fish> in <soup> तब True देता है जब <fish>, <soup> का सदस्य हो (यानी <fish>, <soup> का उपसमुच्चय हो या उसके अंदर आता हो), वरना False देता है।
<fish> not in <soup> इसका उल्टा यानी <fish> in <soup> के विपरीत नतीजा लौटाता है।
स्ट्रिंग और bytes टाइप के लिए, <name> in <fullname> तब True है जब और सिर्फ तभी <name>, <fullname> की सबस्ट्रिंग हो।
# A set of lucky numbers.
>>> lucky_numbers = {11, 22, 33}
>>> 22 in lucky_numbers
True
>>> 44 in lucky_numbers
False
# A dictionary of employee information.
>>> employee = {'name': 'John Doe', 'id': 67826, 'age': 33, 'title': 'ceo'}
# Checking for the membership of certain keys.
>>> 'age' in employee
True
>>> 33 in employee
False
>>> 'lastname' not in employee
True
# Checking for substring membership
>>> name = 'Super Batman'
>>> 'Bat' in name
True
>>> 'Batwoman' in name
False
ऑब्जेक्ट की तुलना का व्यवहार rich comparison methods को लागू करके अपने हिसाब से बदला जा सकता है।
ज़्यादा जानकारी के लिए Python ट्यूटोरियल: क्लास, Python Classes and Magic Methods (Dan Bader) और विशेष मेथड नाम देखिए।