Path: csiph.com!fu-berlin.de!uni-berlin.de!not-for-mail From: Chris Angelico Newsgroups: comp.lang.python Subject: Re: True/False value testing Date: Thu, 7 Jan 2016 22:50:28 +1100 Lines: 64 Message-ID: References: <568e3fb4$0$659$426a74cc@news.free.fr> <877fjl7i30.fsf@elektro.pacujo.net> Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 X-Trace: news.uni-berlin.de X5uEsncrCmXK2/tP+KchlwbsukDQBB1meMrW7HuJakUQ== Return-Path: X-Original-To: python-list@python.org Delivered-To: python-list@mail.python.org X-Spam-Status: OK 0.000 X-Spam-Evidence: '*H*': 1.00; '*S*': 0.00; 'received:209.85.223': 0.03; 'value,': 0.03; 'true,': 0.04; 'false,': 0.07; 'false.': 0.07; 'objects,': 0.07; 'cc:addr:python-list': 0.09; 'integers': 0.09; 'thrown': 0.09; 'jan': 0.11; 'def': 0.13; 'thu,': 0.15; '"is': 0.16; '2016': 0.16; '__lt__': 0.16; '__lt__(self,': 0.16; '__ne__(self,': 0.16; 'boolean': 0.16; 'from:addr:rosuav': 0.16; 'from:name:chris angelico': 0.16; 'integers,': 0.16; 'nan': 0.16; 'numpy': 0.16; 'received:io': 0.16; 'received:psf.io': 0.16; 'similarly,': 0.16; 'stirring': 0.16; 'wrote:': 0.16; 'implementing': 0.18; 'integer': 0.18; '>>>': 0.20; 'cc:2**0': 0.20; 'cc:addr:python.org': 0.20; 'arrays': 0.22; '(or': 0.23; 'this:': 0.23; 'import': 0.24; 'header:In-Reply-To:1': 0.24; "doesn't": 0.26; 'chris': 0.26; 'compare': 0.27; 'message- id:@mail.gmail.com': 0.27; 'values': 0.28; 'actual': 0.28; 'looks': 0.29; 'comparison': 0.29; 'operators': 0.29; 'objects': 0.29; 'subject:/': 0.30; 'skip:_ 10': 0.32; 'class': 0.33; 'received:google.com': 0.35; 'false': 0.35; 'involving': 0.35; 'something': 0.35; 'but': 0.36; 'received:209.85': 0.36; 'pm,': 0.36; 'subject:: ': 0.37; 'being': 0.37; 'received:209': 0.38; 'self': 0.38; 'whatever': 0.39; 'save': 0.60; 'overload': 0.66; 'fact,': 0.67; 'guaranteed': 0.67; 'special': 0.73; 'chrisa': 0.84; 'subject:value': 0.84; 'to:none': 0.91; 'subject:True': 0.93 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:cc :content-type; bh=Gdm+SKDQd9CvrkQmhk6Y4AViMmPbsRwGdtgBL83M53U=; b=u4Ol2eibuhfYT4ZCqWzmVYkdB1KOVPrrC8Kf3yVH2DJB4HCOPN066hl98+opzcEwvj jr6d38mChH4pd2ZpCqNXRY94j2n0qsZNy45e483LD1ek2MgLSAfS4Ii3Ihk1s/RoGijZ fEr+nZQS0s/pt8YsdLdYqYdbifBUMB2UHYciTL68k1Xs8n8DNAxaZ90YRNFY1x/+zMZm SHxV9hpNDJRnvY9vw7/0RI8xxkFcsvqVPcf6Dv4kXCnVrhE95kthQZWRAkfyGcRJXnoJ pzE5RvkK12H217Atj/WPcLKHUg580xPoESewaT7zgKVDsVX/s/9rVZhWTWVS5cNuCjkq 1spQ== X-Received: by 10.107.40.76 with SMTP id o73mr33971735ioo.157.1452167428370; Thu, 07 Jan 2016 03:50:28 -0800 (PST) In-Reply-To: <877fjl7i30.fsf@elektro.pacujo.net> X-BeenThere: python-list@python.org X-Mailman-Version: 2.1.20+ Precedence: list List-Id: General discussion list for the Python programming language List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Xref: csiph.com comp.lang.python:101335 On Thu, Jan 7, 2016 at 10:19 PM, Marko Rauhamaa wrote: > Chris Angelico : > >> However, none of these will compare *equal* to the Boolean values True >> and False, save for the integers 1 and 0. In fact, True is a special >> form of the integer 1, and False is a special form of the integer 0; > > Stirring the pot: > > >>> (2 < 3) is True > True > > but is that guaranteed? Yes. When you do comparisons involving integers, the result is an actual boolean value - not just a truthy value, but the exact value True or False. Those values, being singletons (or a doubleton, or whatever you want to call it), will always be the same objects, ergo the "is True" part must always pass. However, if arbitrary objects are thrown into the mix, the guarantee doesn't hold. Here's one way of implementing a "sticky NaN" that infects all operations: class NaN: def __lt__(self, other): return self __gt__ = __ge__ = __le__ = __lt__ def __eq__(self, other): return False def __ne__(self, other): return True def __new__(cls): if not hasattr(cls, "_inst"): cls._inst = super().__new__(cls) return cls._inst def __repr__(self): return "NaN" NaN = NaN() And it looks something like this: >>> NaN < 1 NaN >>> 1 < NaN NaN >>> NaN > 1 NaN >>> 1 > NaN NaN >>> NaN == NaN False Similarly, numpy arrays overload operators to perform elementwise comparisons: >>> import numpy >>> numpy.array(range(10)) array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> _ < 5 array([ True, True, True, True, True, False, False, False, False, False], dtype=bool) But with integers, and with most other built-in types, the comparison operators are indeed guaranteed to return either True or False. ChrisA