Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Keeping to 79 char line limit in Python with multiple indents

I understand that to write good Python code, I should keep my lines to no more than 79 characters.

This is fine most of the time, but if I have various nested for loops and if statements themselves nested within a class, I might easily find that I have 5 or 6 indents (ie 20-24 characters, if I'm indenting by 4 spaces a time) before I start. Then the 79 character limit becomes quite tricky. I'm aware of various tricks like implicit continuations within brackets and using brackets to concatenate long strings, but even so, it gets a bit fiddly.

So, what do you gurus advise?

Indenting by 2 spaces instead of 4 would help, but is that considered good style? Not sure it would help make my code more readable, and I note that PEP8 says to use 4 spaces.

If I find I have multiple levels of indents, is that perhaps I sign that I'm writing bad code? And if so, any helpful tips or tricks for ways to avoid too much nesting?

Am I right in trying to stick to the 79 character recommendation in the first place?

Or do I just have to get used to a lot of statements broken over multiple lines?

Thanks Adam

like image 581
Adam Jacobs Avatar asked Oct 24 '13 09:10

Adam Jacobs


1 Answers

1. Loops

You can often use itertools.product or itertools.combinations to transform nested loops to a single loop.

When the loops are independent, use product. For example, these nested loops:

for x in range(3):
    for y in range(5):
        for z in range(7):
            print((x, y, z))

become the single loop:

from itertools import product
for x, y, z in product(range(3), range(5), range(7)):
    print((x, y, z))

When the loop indices must be distinct, then you can use combinations. For example, these nested loops:

for start in range(length - 1):
    for end in range(start + 1, length):
        print((start, end))

become the single loop:

from itertools import combinations
for start, end in combinations(range(length), 2):
    print((start, end))

See here for a real-life example using product, and here for an example using combinations.

2. Conditions

When you have lots of if statements, it's often possible to reorganize the code to save indentation steps, and at the same time make the code clearer. The basic idea is to dispose of errors first, and then cases in which you can return immediately, so that the main body of the condition doesn't need to be indented so far (or, in many cases, at all). For example, if you have code like:

if x >= 0:
    if x == 0:
        return 1
    else:
        # ... main body here ...
        return result
else:
    raise ValueError("Negative values not supported: {!r}".format(x))

Then you can reorganize the code like this:

if x < 0:
    raise ValueError("Negative values not supported: {!r}".format(x))
if x == 0:
    return 1
# ... main body here ...
return result

which saves you two levels of indentation for the main body.

like image 189
Gareth Rees Avatar answered Oct 20 '22 00:10

Gareth Rees