Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 918
renatov Avatar asked May 10 '15 03:05

renatov


People also ask

Is Empty list equal to none?

Usually, an empty list has a different meaning than None ; None means no value while an empty list means zero values.

Why is empty list false?

Empty lists are considered False in Python, hence the bool() function would return False if the list was passed as an argument. Other methods you can use to check if a list is empty are placing it inside an if statement, using the len() methods, or comparing it with an empty list.

Can a list equal none Python?

The empty list, [] , is not equal to None . However, it can evaluate to False --that is to say, its "truthiness" value is False .

Does empty list evaluate to false?

In Python, empty list object evaluates to false. Hence following conditional statement can be used to check if list is empty.


2 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.

like image 97
thefourtheye Avatar answered Oct 06 '22 16:10

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)
like image 40
Sylwit Avatar answered Oct 06 '22 15:10

Sylwit