1. Loops
You can often use itertools.product or itertools.combinations to convert nested loops into a single loop.
If 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))
will become a single loop:
from itertools import product for x, y, z in product(range(3), range(5), range(7)): print((x, y, z))
When loop indices should be different, 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))
will become a single loop:
from itertools import combinations for start, end in combinations(range(length), 2): print((start, end))
See here for a real-time example using product and here for an example using combinations .
2. Terms
When you have many if , you can often reorganize the code to preserve the indentation steps and at the same time make the code more understandable. The main idea is to eliminate the errors first, and then the cases in which you can return immediately, so that the main part of the condition should not be indented so far (or, in many cases, in general). For example, if you have code:
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 as follows:
if x < 0: raise ValueError("Negative values not supported: {!r}".format(x)) if x == 0: return 1 # ... main body here ... return result
which will save you two levels of indentation for the main body.