-1

I expected bool(1) to equate to True using Python - it does - then I expected other integers to error when converted to bool but that doesn't seem to be the case:

>>> x=23 #<-- replace with any integer
>>> bool(x)
True

What is happening? Am I misunderstanding bool(x) - does this not convert x to a Boolean data type?


A lot of comments about why I find this counter-intuitive. If I write the above like the below then, on first sight with no knowledge of the language, it would seem counter-intuitive:

>>>True == bool(23)
True
whytheq
  • 34,466
  • 65
  • 172
  • 267
  • 1
    `bool(-1)` is `True`. If you're talking about integers, only `bool(0)` is `False`. – Brian Oct 08 '13 at 18:58
  • You can also check it here for a bit more info: http://docs.python.org/3/library/functions.html#bool – Rivasa Oct 08 '13 at 18:59
  • Why would you expect other integer values to be non-convertible to a bool? – Marcin Oct 08 '13 at 18:59
  • You shouldn't assume that `True` has any particular non-zero value; it's an implementation detail that it has any integer value at all, let alone 1 specifically. – chepner Oct 08 '13 at 19:01
  • If you know that `bool(23)` is `True`, why would you not expect `True == bool(23)`? – Kevin Oct 08 '13 at 19:35
  • @Kevin no - I'm saying if I knew nothing (not far of!) and saw `True == bool(23)` I'd be surprised to see it evaluate to `True`. – whytheq Oct 08 '13 at 19:37

4 Answers4

13

From 5.1 Truth Value Testing:

The following values are considered false:

  • None
  • False
  • zero of any numeric type, for example, 0, 0L, 0.0, 0j.
  • any empty sequence, for example, '', (), [].
  • any empty mapping, for example, {}.
  • instances of user-defined classes, if the class defines a __nonzero__() or __len__() method, when that method returns the integer zero or bool value False.

All other values are considered true — so objects of many types are always true.

Ashwini Chaudhary
  • 244,495
  • 58
  • 464
  • 504
Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • +1 ok - I like this. At first glance to me it seems crazy ...just 0 amongst the integers that is False with every other being True. Now I see the answer though it seems ok - why should just 0==False, 1==True and all others be some sort of error: it's just a decision that the language designer makes. – whytheq Oct 08 '13 at 19:25
  • @whytheq I wouldn't say it's a language specific thing. It's pretty common in programming world to denote `0` as `falsy`, and everything else as `truthy`. Things become easy to handle with this. For the reverse case though, `True` are always converted to `1`, and `False` to `0`. Some language however don't have such mapping from numeric values to boolean values, like `Java`. – Rohit Jain Oct 08 '13 at 19:28
  • @RohitJain There are languages that don't follow this though. In Ruby, `0` is not falsy. Only `false` and `nil` are treated as `false`. – Cezar Oct 08 '13 at 19:57
  • @Cezar Yeah that's what I said in my last line. Same is true with `Java`. No mapping from numerical value to boolean value. – Rohit Jain Oct 08 '13 at 19:58
2

bool's purpose is not to convert a value to the bool data type, per se. Rather, it returns whether the value is truthy, i.e. it behaves in the same manner that this function does:

def bool_mimic(val):
    if val:
        return True
    else:
        return False

From the docs:

bool([x])

Convert a value to a Boolean, using the standard truth testing procedure [see Rohit's answer]. If x is false or omitted, this returns False; otherwise it returns True. bool is also a class, which is a subclass of int. Class bool cannot be subclassed further. Its only instances are False and True.

In the case of ints, the only non-truthy integer is 0.

Community
  • 1
  • 1
Claudiu
  • 224,032
  • 165
  • 485
  • 680
  • @Nirk: no, but it's relevant and it's a common convention to mark text that isn't in the original quote with square brackets. Hardly seems worth a downvote if that was you.. – Claudiu Oct 08 '13 at 19:16
  • in retrospect a downvote probably wasn't warranted. un-downvoted – SheetJS Oct 08 '13 at 19:19
  • +1 so more like a test of existence: although 0 exists. This doesn't exist = () – whytheq Oct 08 '13 at 19:28
  • @whytheq: hmm sort of. The method to override this behavior should give you a hint - it's called `__nonzero__`. then it's a matter of convention to define empty tuples & lists & dicts as "zero" and ones with elements in them as "nonzero". practically it makes for nice-looking code, IMO, but I'm also very used to it so I might be biased. – Claudiu Oct 08 '13 at 19:45
2

bool(x) converts its argument to Bool by using the standard truth testing procedure. Anything that would return true on an if test, for example, will return True when passed as the argument to bool.

Check Truth Value Testing to see which values are treated as True or False in Python

Cezar
  • 55,636
  • 19
  • 86
  • 87
1

As other posters have mentioned, its giving true on any non-zero integer.

Its kind of similar to other things in python, like mentioned here:

Python 'If not' syntax

(Rohit quotes a good paragraph about truth testing)

Community
  • 1
  • 1