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.