Python and indentation

2010-04-18

I don’t really like significant indentation, as implemented in Python. A good starting point for discussion can be found here, but for the time being I will rather focus on the way indentation pattern is checked within Python.

It is worth remembering that both tabs and soft wrap will honour the definition of a correct indentation level. According to the reference documentation, but see also PEP 8,

Leading whitespace (spaces and tabs) at the beginning of a logical line is used to compute the indentation level of the line, which in turn is used to determine the grouping of statements. First, tabs are replaced (from left to right) by one to eight spaces such that the total number of characters up to and including the replacement is a multiple of eight (this is intended to be the same rule as used by Unix). The total number of spaces preceding the first non-blank character then determines the line’s indentation. Indentation cannot be split over multiple physical lines using backslashes; the whitespace up to the first backslash determines the indentation. Python v2.6.5 documentation

For example, the following snippet is correctly indented:

def perm(l):
if len(l) <= 1:
  return [l]
r = []
for i in range(len(l)):
  s = l[:i] + l[i+1:]
  p = perm(s)
  for x in p:
    r.append(l[i:i+1] + x)
return r

About balancing indentation, a colleague of mine lets me realize that in fact Python is just storing (I assume this is done with a stack) a counter for the number of leading spaces. For example, we could have something like [24466442] which actually reflects the following code structure:

••
••••
••••
••••••
••••••
••••
••••
••

Here is a short solution to the balanced parentheses problem. This is taken litterally from Miller and Ranum, Problem Solving with Algorithms and Data Structures using Python, 2006. The complete source code can be downloaded from Github as Gist 549159.

Now, you understand why I don’t like significant indentation: You have to read your code one line after the other to be sure that block are well formed, especially with complex if-else statements like the ones above.

Here are examples of use of these functions:

>>> st1 = ‘((()))’
>>> parChecker(st1)
True
>>> st2 = ‘((()()))’
>>> parChecker(st2)
True
>>> st3 = ‘((()(()))’
>>> parChecker(st3)
False

Obviously, this code can be adapted to count the number of spaces without much effort.

---

Articles with the same tag(s):

Light Table and interactive live coding
Python for interactive scientific data visualization
Emacs auto-completion for Python
Interacting with Weka from Jython
IPython 0.11, the new killer app
Installing numpy+scipy on OS X Lion
Python for statistical computing
Bayesian analysis with Python
Visual psychophysics with Python
Customizing iPython

---