-1
Python 3.10.6 (tags/v3.10.6:9c7b4bd, Aug 1 2022, 21:53:49) [MSC v.1932 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license ()" for more information.
print( False == [])
False
print (bool ([]))
False
print (bool (1))
True

In the example above I tried print( False==[]) in python and it evaluates to False instead of True, but as both the value of False and bool([]) is False it should be True right?

The bool value of [] shows false but when I do False == [] it shows False, why is it not showing True?

moken
  • 3,227
  • 8
  • 13
  • 23
Mudge
  • 9
  • 3
    An empty list is falsey but not False. However, you can assert that bool([]) == False – DarkKnight Jul 09 '23 at 09:26
  • 1
    If you have to decide in a boolean context whether an empty list is more *truthy* or *falsey*, then it's *falsey*. That does not mean it is *equal to `False`*. – deceze Jul 09 '23 at 09:29

1 Answers1

0

Just because bool(x) evaluates to False doesn't mean x is equal to False. In terms of equality comparison, False is basically just zero.

For example, bool("") evaluates to False, but "" is not equal to False. Similarly, bool([]) evaluates to False, but [] is not equal to False.

On the other hand, 0 == False and 0.0 == False are both true, since in those cases it's doing numeric comparisons.

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
  • 1
    That last one is an implementation detail, which should not be confused with some deliberate logic. – deceze Jul 09 '23 at 09:38
  • @deceze Isn't `bool` guaranteed to subclass `int`, with `int(False)` being `0` and `int(True)` being `1`? – Tom Karzes Jul 09 '23 at 09:39
  • @deceze The Python 3 library documentation says "In addition, Booleans are a subtype of integers." So that much is guaranteed. Are you saying that `False` may have a different integer value than zero? I don't see how that can be true. – Tom Karzes Jul 09 '23 at 09:45
  • Yes, it is de facto guaranteed, but not necessarily because someone designed it this way, but because it's been implemented this way and changing it now would break things. That does not mean it should be mentioned in the same breath as `[] != False`, because then there seems to be little internal logic as to what equals or doesn't equal what. – deceze Jul 09 '23 at 09:50
  • FWIW: *"In an ideal world, bool might be better implemented as a separate integer type that knows how to perform mixed-mode arithmetic. However, inheriting bool from int eases the implementation enormously [..]"* https://peps.python.org/pep-0285/ — So, yes, a large part of the reason why it's been designed this way is implementation details, but because of this decision it's also been baked into the design. That doesn't mean Python 4 mightn't change this decision. – deceze Jul 09 '23 at 09:58
  • @deceze If `bool` is changed to be a separate integer type, then I assume `False` would still compare equal to `0` and `True` would still compare equal to `1`. Are you suggesting that `False` may possibly be changed to compare equal to things like `[]` or `""`? – Tom Karzes Jul 09 '23 at 10:03
  • No. I'm saying that `[] != False` and `"" != False` make sense, so why then `0 == False`? That somewhat breaks the logic and feels more like an exception to the rule. So why does this exception to the rule exist? Mostly because it made the implementation easier. So what if the designers decided in Python 4 to make the rule more uniform and also make `0 != False`? I'm not saying anyone is considering that, but it would make sense to do. – deceze Jul 09 '23 at 10:08
  • @deceze I think people find it convenient for `False` to behave like `0` and `True` to behave like `1`. For example, if you have a list of `True`/`False` values, you can do `sum(lst)` to get the number of `True` values. It's also similar to languages that don't have a true bool type, or that added it later, and use `0` for a canonical false value and `1` for a canonical true value. For example, you can do things like `sum(x == y for x, y in zip(lst1, lst2))`. – Tom Karzes Jul 09 '23 at 10:13
  • Yes, because it is implemented as it is, you can do those things, and that can lead to code which is easier than if bools were not a subtype of int. Still, that's a useful side effect of an exception to an otherwise very consistent rule. You can also come up with opposite examples, where `0 == False` can come as a surprise and cause bugs: `if foo == 0: .. elif foo == 1: ..` — Should `foo` unexpectedly contain `False` here, you may have unexpected behaviour in your code. – deceze Jul 09 '23 at 10:20
  • @deceze So you're suggesting that bools should never compare equal to non-bools, is that right? So `False` would only compare equal to `False`, or `False` in a type subclassed from bool? And `False < 1` would give an error, right? It would mean some of those idioms wouldn't be quite as terse, but it might avoid some confusion. But it also sounds like `bool` would no longer act like a numeric type, much less an integer type. – Tom Karzes Jul 09 '23 at 10:31
  • Yes, that would be the expected behavior that’s in line with the rest of the equality comparison rules. – deceze Jul 09 '23 at 10:33
  • @deceze It seems inconsistent to me. If `bool` is a integer type, regardless of whether it subclasses `int`, then you would expect `bool(0)` to compare equal to `0`, just as `0.0` is equal to `0`, and `0j` is equal to zero, and `Fraction(0)` is equal to `0`, and `Decimal(0)` is equal to `0`, etc. So you'd exiect `bool(0)` to equal `0`, just as it does for any other numeric type. To me, it would only make sense if `bool` were no longer a numeric type, much less an integer type. But it seems useful for it to be an integer type. – Tom Karzes Jul 09 '23 at 10:37
  • Fractions and decimals and floats are all numeric types, it makes complete sense and is convenient for them to compare to each other. Bools OTOH are not intrinsically numeric. At no point does `False` or `True` look anything like a number, except when trying to compare them to one. That’s IMHO more surprising. I would *not* necessarily expect `bool(0) == 0`, except if I’m influenced by C-like languages to begin with. – deceze Jul 09 '23 at 10:40
  • @deceze Ok, it sounds like you're suggesting that `bool` should not be a numeric type. The quote you gave earlier said "In an ideal world, bool might be better implemented as a separate integer type that knows how to perform mixed-mode arithmetic." It sounds like that isn't what you want. – Tom Karzes Jul 09 '23 at 10:47
  • True, bools behave exceptionally, influenced from a C design thinking. In *my* ideal world, they wouldn’t. But I do concede that the advantages probably outweigh the demerits. Still, it should be explained as an exception to the rule IMO, not something that should make obvious intuitive sense. – deceze Jul 09 '23 at 10:50
  • @deceze I agree that it's not immediately obvious that bools should be a numeric type. But in the current implementation, they're just integers that identify as bools, and if you do almost anything with them, they behave like integers. But it sounds like the language intent is that they be an integer type, even if they don't subclass `int`. In that case, `0 == False` and `0.0 == False` would remain `True` even if that change was made to decouple them from the `int` class. – Tom Karzes Jul 09 '23 at 10:56