Zen of Python 'Explicit is better than implicit'

4.2k views Asked by At

I'm trying to understand what 'implicit' and 'explicit' really means in the context of Python.

a = []

# my understanding is that this is implicit
if not a:
   print("list is empty")

# my understanding is that this is explicit
if len(a) == 0:
   print("list is empty")

I'm trying to follow the Zen of Python rules, but I'm curious to know if this applies in this situation or if I am over-thinking it?

3

There are 3 answers

1
Mad Physicist On BEST ANSWER

The two statements have very different semantics. Remember that Python is dynamically typed.

For the case where a = [], both not a and len(a) == 0 are equivalent. A valid alternative might be to check not len(a). In some cases, you may even want to check for both emptiness and listness by doing a == [].

But a can be anything. For example, a = None. The check not a is fine, and will return True. But len(a) == 0 will not be fine at all. Instead you will get TypeError: object of type 'NoneType' has no len(). This is a totally valid option, but the if statements do very different things and you have to pick which one you want.

(Almost) everything has a __bool__ method in Python, but not everything has __len__. You have to decide which one to use based on the situation. Things to consider are:

  • Have you already verified whether a is a sequence?
  • Do you need to?
  • Do you mind if your if statement crashed on non-sequences?
  • Do you want to handle other falsy objects as if they were empty lists?

Remember that making the code look pretty takes second place to getting the job done correctly.

5
Harlin On

Try to think of:

if not a:
    ...

as shorthand for:

if len(a) == 0:
    ...

I don't think this is a good example of a gotcha with Python's Zen rule of "explicit" over "implicit". This is done rather mostly because of readability. It's not that the second one is bad and the other is good. It's just that the first one is more skillful. If one understands boolean nature of lists in Python, I think you find the first is more readable and readability counts in Python.

1
ips1 38 On

Though this question is old, I'd like to offer a perspective.

In a dynamic language, my preference would be to always describe the expected type and objective of a variable in order to offer more purpose understanding. Then use the knowledge of the language to be succinct and increase readability where possible (in python, an empty list's boolean result is false). Thus the code:

lst_colours = [] 

if not lst_colours: 
  print("list is empty")

Even better to convey meaning is using a variable for very specific checks.

lst_colours = []
b_is_list_empty = not lst_colours

if b_is_list_empty: 
  print("list is empty")

Checking a list is empty would be a common thing to do several times in a code base. So even better such things in a separate file helper function library. Thus isolating common checks, and reducing code duplication.

lst_colours = []

if b_is_list_empty(lst_colours): 
  print("list is empty")


def b_is_list_empty (lst):
  ......

Most importantly, add meaning as much as possible, have an agreed company standard to chose how to tackle the simple things, like variable naming and implicit/explicit code choices.