কেন 0 <0 == 0 অভিব্যক্তি পাইথনে মিথ্যা প্রত্যাবর্তন করে?


136

পাইথন ২.6-এর ক্যু.পি.-এর দিকে তাকিয়ে, আমি এই নির্মাণটিটি দেখতে পেয়েছিলাম যা কিছুটা অদ্ভুত বলে মনে হয়েছিল:

def full(self):
    """Return True if the queue is full, False otherwise
    (not reliable!)."""
    self.mutex.acquire()
    n = 0 < self.maxsize == self._qsize()
    self.mutex.release()
    return n

যদি maxsize0 হয় তবে সারিটি কখনই পূর্ণ হয় না।

আমার প্রশ্ন এই কেসটি কীভাবে কাজ করে? কীভাবে 0 < 0 == 0মিথ্যা বলে বিবেচিত হবে?

>>> 0 < 0 == 0
False
>>> (0) < (0 == 0)
True
>>> (0 < 0) == 0
True
>>> 0 < (0 == 0)
True

0 <অজগরের ক্ষেত্রে মিথ্যাটির সমান কি?
মেরিনো Šimić

3
@ মারিনো Šিমি: ওপি-র প্রশ্নে প্রদর্শিত দ্বিতীয় উদাহরণ থেকে >>> (0) < (0 == 0), এটি পরিষ্কারভাবে নয়।
মার্টিনিউ

3
একটি কারণ আপনাকে n = 0 < self.maxsize == self._qsize()কোনও ভাষাতেই প্রথম স্থানের মতো কোড লিখতে হবে না । আপনার চোখ যদি লাইনটি জুড়ে পিছনে পিছনে পিছনে পিছনে বেশ কয়েকবার ঘুরতে থাকে তবে কী চলছে তা নির্ধারণ করার জন্য, এটি কোনও লিখিত লাইন নয়। এটি বেশ কয়েকটি লাইনে বিভক্ত করুন।
ব্লুরাজা - ড্যানি পিফ্লুঘুফুট

2
@ ব্লু: আমি এ জাতীয় তুলনা সেভাবে লেখার সাথে একমত নই তবে এটিকে আলাদা লাইনে বিভক্ত করা দুটি তুলনার জন্য কিছুটা ওভারবোর্ডে চলেছে। আমি আশা করি আপনি বোঝাতে চেয়েছেন, এটি আলাদা তুলনা মধ্যে বিভক্ত। ;)
জেফ মার্কাডো

2
@ ব্লু: আমি এটি লিখিনি, এটি পাইথন ২.6 এ রয়েছে। আমি কেবল কী হচ্ছে তা বোঝার চেষ্টা করছিলাম।
মার্সেলো

উত্তর:


113

আমি বিশ্বাস করি যে পরিসরের তুলনাটি প্রকাশ করা সহজ করার জন্য পাইথনের রিলেশনাল অপারেটরগুলির ক্রমগুলির জন্য বিশেষ কেস হ্যান্ডলিং রয়েছে। বলার 0 < x <= 5চেয়ে বলতে সক্ষম হওয়া অনেক সুন্দর (0 < x) and (x <= 5)

এগুলিকে শিকলযুক্ত তুলনা বলা হয় । এবং এটি তাদের জন্য ডকুমেন্টেশনের একটি লিঙ্ক।

আপনি যে অন্যান্য ক্ষেত্রে কথা বলছেন সেগুলির সাথে প্রথম বন্ধনী একটি রিলেশনাল অপারেটরকে অন্যের আগে প্রয়োগ করতে বাধ্য করে এবং তাই এগুলি আর শৃঙ্খলাবদ্ধ তুলনা হয় না। এবং যেহেতু Trueএবং Falseপূর্ণসংখ্যার হিসাবে মান রয়েছে আপনি উত্তরগুলি প্যারেন্থাইজড সংস্করণগুলির বাইরে পাবেন।


এইগুলির মধ্যে কয়েকটি তুলনা চেষ্টা করে ইন্টার () এবং বুল () নির্দিষ্ট করা আকর্ষণীয়। আমি বুঝতে পেরেছিলাম যে কোনও শূন্যের বুল () ১ টি। অনুমান করুন আমি এই চিন্তার পরীক্ষার আগে আমি কখনই
বুল

আপনি কি পরিবর্তে এই বিভাগে লিঙ্ক করতে চান? docs.python.org/2/references/expressions.html#comparisons
tavnab

@ টভনব - হ্যাঁ আমি এটি ঠিক করার জন্য মনে রাখার চেষ্টা করব। আমি সম্পাদনা ইতিহাস পরীক্ষা করতে যাচ্ছি। আমি ভুল করব বলে মনে হচ্ছে না। 😕
সর্বশক্তিমান

42

কারণ

(0 < 0) and (0 == 0)

হয় False। আপনি তুলনা অপারেটরগুলিকে একসাথে চেইন করতে পারেন এবং সেগুলি স্বয়ংক্রিয়ভাবে জোড়াযুক্ত তুলনাতে প্রসারিত হয়।


সম্পাদনা - পাইথনে সত্য এবং মিথ্যা সম্পর্কে স্পষ্টতা

পাইথনে Trueএবং এটির Falseউদাহরণ মাত্র bool, যা একটি সাবক্লাস int। অন্য কথায়, Trueসত্যিই মাত্র 1।

এর মুল বক্তব্যটি হ'ল আপনি একটি বুলিয়ান তুলনার ফলাফলটি ঠিক পূর্ণসংখ্যার মতো ব্যবহার করতে পারেন। এটি বিভ্রান্তিকর জিনিসগুলিতে বাড়ে

>>> (1==1)+(1==1)
2
>>> (2<1)<1
True

তবে এগুলি কেবল তখনই ঘটবে যখন আপনি তুলনাগুলি বন্ধনীরূপে স্থাপন করুন যাতে সেগুলি প্রথমে মূল্যায়ন করা হয়। অন্যথায় পাইথন তুলনা অপারেটরগুলি প্রসারিত করবে।


2
আমি গতকাল পূর্ণসংখ্যা হিসাবে বুলিয়ান মানগুলির ব্যবহারের জন্য একটি আকর্ষণীয় ব্যবহার দেখেছি। এক্সপ্রেশনটি 'success' if result_code == 0 else 'failure'আবার লিখিত হতে পারে ('error', 'success')[result_code == 0], এর আগে আমি কখনই কোনও বুলিয়ান দেখিনি যে কোনও তালিকা / টুপলে কোনও আইটেম নির্বাচন করতে ব্যবহৃত হয়েছিল।
অ্যান্ড্রু ক্লার্ক

পাইথন ২.২-এর আশেপাশে 'বুল' যুক্ত হয়েছিল।
এমআরএবি

18

আপনার যে অদ্ভুত আচরণের মুখোমুখি হচ্ছে তা অজগর ক্ষমতা থেকে শৃঙ্খলার শঙ্কায় আসে। যেহেতু এটি 0 টি 0 এর চেয়ে কম নয়, এটি সম্পূর্ণ এক্সপ্রেশনটিকে ভ্যালুতে নির্ধারণ করে। যত তাড়াতাড়ি আপনি এটি পৃথক অবস্থায় বিচ্ছিন্ন করার সাথে সাথে আপনি কার্যকারিতা পরিবর্তন করছেন। এটি প্রাথমিকভাবে মূলত পরীক্ষা করছে যে a < b && b == cআসল বিবৃতি জন্য a < b == c

আরেকটি উদাহরণ:

>>> 1 < 5 < 3
False

>>> (1 < 5) < 3
True

1
ওএমজি, ওও a < b && b == cহিসাবে একইa < b == c
কিরিল কিরভ 20'11

9
>>> 0 < 0 == 0
False

এটি একটি শৃঙ্খলিত তুলনা। পরিবর্তে প্রতিটি যুগল করে তুলনা করা সত্য হলে এটি সত্য হয়। এটির সমতুল্য(0 < 0) and (0 == 0)

>>> (0) < (0 == 0)
True

এটি সমান 0 < Trueযা সত্যকে মূল্যায়ন করে।

>>> (0 < 0) == 0
True

এটি সমান False == 0যা সত্যকে মূল্যায়ন করে।

>>> 0 < (0 == 0)
True

0 < Trueযার সমান , উপরে হিসাবে, সত্যকে মূল্যায়ন করে।


7

বিচ্ছিন্নতা (বাইট কোডস) এর দিকে তাকানো কেন 0 < 0 == 0এটি স্পষ্ট False

এই মত প্রকাশের একটি বিশ্লেষণ এখানে দেওয়া হয়েছে:

>>>import dis

>>>def f():
...    0 < 0 == 0

>>>dis.dis(f)
  2      0 LOAD_CONST               1 (0)
         3 LOAD_CONST               1 (0)
         6 DUP_TOP
         7 ROT_THREE
         8 COMPARE_OP               0 (<)
        11 JUMP_IF_FALSE_OR_POP    23
        14 LOAD_CONST               1 (0)
        17 COMPARE_OP               2 (==)
        20 JUMP_FORWARD             2 (to 25)
   >>   23 ROT_TWO
        24 POP_TOP
   >>   25 POP_TOP
        26 LOAD_CONST               0 (None)
        29 RETURN_VALUE

বিজ্ঞপ্তি লাইন 0-8: এই লাইনগুলি পরীক্ষা করে 0 < 0যা স্পষ্টতই Falseপাইথন স্ট্যাকের দিকে ফিরে আসে কিনা ।

এখন লাইন ১১ টি লক্ষ্য করুন: JUMP_IF_FALSE_OR_POP 23 এর অর্থ হল যদি 0 < 0রিটার্নগুলি False23 লাইনে একটি লাফ দেয়।

এখন, 0 < 0হয় False, তাই লাফ নেওয়া হয়, যা দিয়ে স্ট্যাক ছেড়ে একটি Falseযা পুরো অভিব্যক্তি বিনিময়ে মান 0 < 0 == 0, যদিও == 0অংশ এমনকি চেক করা নেই।

সুতরাং, উপসংহারে, উত্তরটি এই প্রশ্নের অন্যান্য উত্তরের মতো বলেছে। 0 < 0 == 0একটি বিশেষ অর্থ আছে। সংকলক এটি দুটি পদে মূল্যায়ন করে: 0 < 0এবং 0 == 0andতাদের মধ্যে যে কোনও জটিল বুলিয়ান অভিব্যক্তিগুলির মতো , যদি প্রথম ব্যর্থ হয় তবে দ্বিতীয়টি এমনকি পরীক্ষা করা হয় না।

আশা করি এটি কিছুটা আলোকিত করে এবং আমি সত্যিই আশা করি যে এই অপ্রত্যাশিত আচরণটি বিশ্লেষণ করার জন্য আমি যে পদ্ধতিটি ব্যবহার করেছি তা ভবিষ্যতে অন্যদেরও একই চেষ্টা করতে উত্সাহিত করবে।


বিপরীত প্রকৌশলটির একটি নির্দিষ্ট বাস্তবায়নকে বাদ দিয়ে চশমা থেকে এটি কাজ করা কি সহজ হবে না?
ডেভিড হেফারনান

না এটি সংক্ষিপ্ত উত্তর। আমি বিশ্বাস করি এটি আপনার ব্যক্তিত্বের উপর নির্ভর করে। যদি আপনি কোনও "ব্ল্যাক বক্স" দেখার সাথে সম্পর্কিত হন এবং আপনার উত্তরগুলি চশমা এবং ডকুমেন্টেশন থেকে পাওয়া পছন্দ করেন তবে এই উত্তরটি আপনাকে কেবল বিভ্রান্ত করবে। আপনি যদি খনন করতে এবং স্টাফের অভ্যন্তরীণ অংশগুলি প্রকাশ করতে চান তবে এই উত্তরটি আপনার জন্য। আপনার মন্তব্য যে এই বিপরীত প্রকৌশলটি কেবলমাত্র একটি নির্দিষ্ট প্রয়োগের ক্ষেত্রে প্রাসঙ্গিক সঠিক এবং এটি অবশ্যই দেখানো উচিত, তবে এটি এই উত্তরের মূল বিষয় ছিল না। যারা যথেষ্ট উত্সাহী তাদের জন্য "ফণার নীচে" এক নজরে নেওয়া অজগরটিতে কতটা সহজ তা একটি বিক্ষোভ।
সাত

1
বিপরীতে ইঞ্জিনিয়ারিংয়ের সমস্যাটি হ'ল এর ভবিষ্যদ্বাণীপূর্ণ শক্তির অভাব। এটি কোনও নতুন ভাষা শেখার উপায় নয়।
ডেভিড হেফারনান

আরেকটি জিনিস যা আমি অবশ্যই যুক্ত করব তা হ'ল চশমা এবং ডকুমেন্টেশনগুলি সর্বদা সম্পূর্ণ হয় না এবং বেশিরভাগ ক্ষেত্রে এই জাতীয় নির্দিষ্ট ক্ষেত্রে উত্তর সরবরাহ করে না। তারপরে, আমি বিশ্বাস করি, উত্তরগুলি খুঁজে পাওয়ার জন্য, অনুসন্ধান করা, তদন্ত করতে এবং গভীরতর পর্যায়ে পৌঁছাতে ভয় পাওয়া উচিত নয়।
সাটা

2

অন্যের x comparison_operator y comparison_operator zযেমন উল্লেখ করা হয়েছে তেমন বাইনাসের (x comparison_operator y) and (y comparison_operator z)সাথে সিনট্যাকটিকাল চিনি যা কেবলমাত্র একবারই মূল্যায়ন করা হয়।

সুতরাং আপনার অভিব্যক্তিটি 0 < 0 == 0সত্যই (0 < 0) and (0 == 0)যা মূল্যায়ন করে False and Trueযা কোনটি সঠিক False


2

সম্ভবত ডক্সের এই উদ্ধৃতিটি সহায়তা করতে পারে:

এগুলি তথাকথিত "সমৃদ্ধ তুলনা" পদ্ধতিগুলি এবং __cmp__()নীচের তুলনায় তুলনামূলক অপারেটরদের জন্য ডাকা হয় । অপারেটর প্রতীক এবং পদ্ধতি নাম মধ্যে চিঠিপত্রের নিম্নরূপ: x<yকল x.__lt__(y), x<=yকল x.__le__(y), x==yকল x.__eq__(y), x!=yএবং x<>y কল x.__ne__(y), x>yকল x.__gt__(y), এবং x>=yকল x.__ge__(y)

একটি সমৃদ্ধ তুলনামূলক পদ্ধতিটি NotImplementedযদি প্রদত্ত যুগল যুক্তির জন্য ক্রিয়াকলাপটি বাস্তবায়ন না করে তবে সিঙ্গলটনে ফিরে আসতে পারে। কনভেনশন দ্বারা, Falseএবং Trueএকটি সফল তুলনার জন্য ফিরে আসে। যাইহোক, এই পদ্ধতিগুলি কোনও মান ফিরিয়ে দিতে পারে, সুতরাং তুলনা অপারেটরটি যদি কোনও বুলিয়ান প্রসঙ্গে ব্যবহার করা হয় (উদাহরণস্বরূপ, যদি একটি বিবৃতি শর্তে), পাইথন bool()ফলাফলটি সত্য বা মিথ্যা কিনা তা নির্ধারণের জন্য মানটি কল করবে ।

তুলনা অপারেটরদের মধ্যে কোনও অন্তর্নিহিত সম্পর্ক নেই। এর সত্যটি মিথ্যা x==yবলে বোঝায় না x!=y। তদনুসারে, সংজ্ঞা দেওয়ার সময় __eq__(), একটিও নির্ধারণ করা উচিত __ne__()যাতে অপারেটররা প্রত্যাশা অনুযায়ী আচরণ করবে। __hash__()হ্যাশযোগ্য অবজেক্ট তৈরির বিষয়ে কিছু গুরুত্বপূর্ণ নোটের জন্য অনুচ্ছেদটি দেখুন যা কাস্টম তুলনা ক্রিয়াকে সমর্থন করে এবং অভিধান কী হিসাবে ব্যবহারযোগ্য able

এই পদ্ধতির কোনও অদল-বদল সংস্করণ নেই (যখন বাম আর্গুমেন্ট অপারেশন সমর্থন করে না তবে ডান আর্গুমেন্টটি ব্যবহার করে); বরং, __lt__()এবং __gt__() একে অপরের প্রতিবিম্ব, __le__() এবং __ge__()একে অপরের প্রতিবিম্ব, এবং __eq__()এবং __ne__() তাদের নিজস্ব প্রতিবিম্ব হয়।

সমৃদ্ধ তুলনা পদ্ধতিতে যুক্তিগুলি কখনই জোর করে না।

এগুলি তুলনা ছিল তবে যেহেতু আপনি তুলনা শৃঙ্খলাবদ্ধ করছেন আপনার জানা উচিত:

তুলনাগুলি নির্বিচারে শৃঙ্খলাবদ্ধ করা যেতে পারে, উদাহরণস্বরূপ, x < y <= zএর সমপরিমাণ x < y and y <= zবাদে কেবলমাত্র একবারে y মূল্যায়ন করা হয় (তবে উভয় ক্ষেত্রে z x এর মূল্যায়ন হয় না যখন x <y মিথ্যা বলে প্রমাণিত হয়)।

সাধারণত, যদি a, b, c, ..., y, z হয় এক্সপ্রেশন এবং op1, op2, ..., opN হয় তুলনা অপারেটর, তবে একটি op1 b op2 c ... y opN z একটি op1 b এর সমতুল্য এবং b op2 c এবং ... y opN z ব্যতীত প্রতিটি অভিব্যক্তি একবারে একবারে মূল্যায়ন করা হয়।


1

এখানে সব তার মহিমা হয়.

>>> class showme(object):
...   def __init__(self, name, value):
...     self.name, self.value = name, value
...   def __repr__(self):
...     return "<showme %s:%s>" % (self.name, self.value)
...   def __cmp__(self, other):
...     print "cmp(%r, %r)" % (self, other)
...     if type(other) == showme:
...       return cmp(self.value, other.value)
...     else:
...       return cmp(self.value, other)
... 
>>> showme(1,0) < showme(2,0) == showme(3,0)
cmp(<showme 1:0>, <showme 2:0>)
False
>>> (showme(1,0) < showme(2,0)) == showme(3,0)
cmp(<showme 1:0>, <showme 2:0>)
cmp(<showme 3:0>, False)
True
>>> showme(1,0) < (showme(2,0) == showme(3,0))
cmp(<showme 2:0>, <showme 3:0>)
cmp(<showme 1:0>, True)
True
>>> 

0

আমি ভাবছিলাম পাইথন ম্যাজিকের মাঝে এটি অদ্ভুত করছে। হিসাবে 1 < 2 < 32 হিসাবে একই 1 এবং 3 এর মধ্যে।

এই ক্ষেত্রে, আমি মনে করি এটি করছে [মাঝারি 0] [বাম 0] এর চেয়ে বড় এবং [ডান 0] এর সমান। মাঝারি 0 বাম 0 এর চেয়ে বড় নয়, সুতরাং এটি মিথ্যাতে মূল্যায়ন করে।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.