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
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
.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With