-3

Coming from javascript, I found pretty bizarre this behaviour:

>>> empty_list = []
>>> empty_list == True
False
>>> empty_list is True
False
>>> empty_list is False
False
>>> empty_list == False
False

And on the other hand:

>>> one_list = [1]
>>> one_list is False
False
>>> one_list is True
False
>>> one_list == False
False
>>> one_list == True
False

Actually, I expected that since:

if []:
  pass # This never done

and

if [4]:
  pass # This is always done

and

>>> not []
True
>>> not [1]
False

A list would convert to a boolean.

I am aware that

>>> bool([])
False
>>> bool([1])
True

So I wonder why not and if perform this conversion, whereas nor in nor == do

Is there any formal explanation for this?

Luis Sieira
  • 29,926
  • 3
  • 31
  • 53
  • 3
    Strange, `bool(empty_list)` returns False on my machine. What version are you using? – Kevin Dec 15 '15 at 14:31
  • `is` tests whether its operands are the same exact object; this is stronger than equality. Only `True` is `True`. – jwodder Dec 15 '15 at 14:32
  • I'm voting "could not reproduce" because `bool([])` is `False` on both Python 2 and Python 3, and I have no idea why you expect the `is` tests to work at all. Obviously no kind of list "is" the boolean singleton of either value. – Two-Bit Alchemist Dec 15 '15 at 14:32
  • Because if not something is True, I expect something to be False – Luis Sieira Dec 15 '15 at 14:35
  • 2
    You are coming from javascript and find Python boolean equivalence incosistent? – LeartS Dec 15 '15 at 14:36
  • 1
    Well `bool([]) == False` and `not bool([]) == True` as you expect, so it seems this is a duplicate, because all that's left of this question stems from your misunderstanding and misapplication of `is` tests. – Two-Bit Alchemist Dec 15 '15 at 14:38
  • 1
    You seem to have now changed your question to invalidate existing answers. Your new question at the bottom is partially internally inconsistent "why ... `if` performs this conversion, whereas... `if` [does not]" and partly self-explanatory. `not` performs a conversion to boolean because its entire purpose is to take the boolean negation. `==` does not convert types in Python probably because such behavior has led to a hideous mess in languages like JavaScript and PHP that did go down this road, and which now have dire warnings about using `==` because it's not even transitive. – Two-Bit Alchemist Dec 15 '15 at 15:36
  • I indeed did change the question, but it was not in order to invalidate existent answers, but to clarify what my problem was. My first version was confusing, and led to the answers I got. I'm actually used to javascript way, and the one I find confusing is python's, actually the answers still apply to the new version of the question. I'm sorry for the mess – Luis Sieira Dec 15 '15 at 15:51

2 Answers2

8

is is an operator that checks object equality. In other words, a is b is true if and only if a and b are two names pointing to the same object in memory.

If you just want plain regular equality or inequality, use == or !=. But note a Boolean will never be equal to a list, because they're simply not the same type. No implicit conversion occurs in Python as it does in Javascript. You still need to explicitly convert the list in Boolean before comparing.

Jasper
  • 3,939
  • 1
  • 18
  • 35
Lærne
  • 3,010
  • 1
  • 22
  • 33
1

Another explanation might be operator precedence: is binds more strongly than not, so

not [1] is True

is evaluated as

not ([1] is True])
== not (False)      # because a list containing 1 is not the boolean True
== True
Jasper
  • 3,939
  • 1
  • 18
  • 35