Is it wrong to use the "==" operator when comparing to an empty list?

Question:

PyCharm (4.0.6) complains when I do a comparison to an empty list using the == operator, but it doesn’t when I use the is operator:

enter image description here

I guess this is something related to PEP 8, but the problem is that when I use the is operator, as PyCharm suggests, I have a false negative. Here is a simple example in iPython shell to show that in this case the == operator seems more appropriate, since the is operator returns a false negative:

In[2]: actions = []
In[3]: actions == []
Out[3]: True
In[4]: actions is []
Out[4]: False

Could someone please explain why PyCharm complains about the == operator when comparing to an empty lists? Am I doing something wrong according to PEP 8?

Asked By: renatov

||

Answers:

Quoting PEP-8’s Programming Recommendations section,

For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

Yes: if not seq:
     if seq:

No: if len(seq)
    if not len(seq)

Since empty sequences are Falsy in Python,

>>> bool([])
False
>>> bool(())
False

you can simply use if not as mentioned in the PEP-8.

Note: You should never use is to compare if two values are equal, because is operator checks if two objects are one and the same, but == checks if two objects are equal.


I dug in to the source code to figure out what is happening. When we do a == [],

>>> dis(compile('if a == []: pass', "string", "exec"))
  1           0 LOAD_NAME                0 (a)
              3 BUILD_LIST               0
              6 COMPARE_OP               2 (==)
              9 POP_JUMP_IF_FALSE       15
             12 JUMP_FORWARD             0 (to 15)
        >>   15 LOAD_CONST               0 (None)
             18 RETURN_VALUE

we are constructing a new list and it would be a very costly operation, just for comparison. On the other hand

>>> dis(compile('if not a: pass', "string", "exec"))
  1           0 LOAD_NAME                0 (a)
              3 POP_JUMP_IF_TRUE         9
              6 JUMP_FORWARD             0 (to 9)
        >>    9 LOAD_CONST               0 (None)
             12 RETURN_VALUE

we are trying to see if the current sequence could be Truthy. This internally checks if the length of the sequence is zero (which is just a simple lookup, as the length of the list is maintained in a variable). If the length is zero, then if not actions: will be Truthy. Here we don’t construct a new list, but we are just checking the length implicitly, instead of explicitly doing

if len(actions) == 0:

So, I am guessing that Python Gurus are suggesting if not seq because there could be performance advantage as well.

Answered By: thefourtheye

According to PEP8 doc you should use

For sequences, (strings, lists, tuples), use the fact that empty sequences are false.

Yes: if not seq:
     if seq:

No: if len(seq)
    if not len(seq)
Answered By: Sylwit
Categories: questions Tags: , , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.