On 1 October 2016 at 10:25, Alexander Heger firstname.lastname@example.org wrote:
I think wasting of indentation levels for a single logical block should be avoided if possible to make the code more legible, otherwise one hits the suggested line length limit too fast - suppose this is now inside a method, you already lose at least 8 char ...
Hence generators, which allow the nested loops to be readily factored out into a named operation.
def iter_interesting_triples(seq1, seq2, seq3): for x in seq1: if p1(x): for y in seq2: if p2(x, y): for z in seq3: if p3(x, y, z): yield x, y, z
for x, y, z in iter_interesting_triples(seq1, seq2, seq3): f(x, y, z)
As you pointed out, the simple cases with no filtering, or only filtering that depends on the value of "z", are already covered by itertools.product:
for x, y, z in itertools.product(seq1, seq2, seq3): f(x, y, z)
for x, y, z in itertools.product(seq1, seq2, seq3): if p(x, y, z): f(x, y, z)
And that step of separating the process of generating the candidate triples from actually doing the work on them also opens up a whole new world of possibilities when it comes to your execution model, like using concurrent.futures to process them in parallel in multiple threads or processes.
There's no question that modeling algorithms as purely procedural code starts breaking down beyond a certain level of complexity. The fact that *not* breaking up our Python code into more modular units gets painful as we start hitting those limits as the author of the code in question is a side effect of that - it's a warning that we have an imminent readability problem, just as written documents start needing section headings to aid reader navigation as they get longer.
As a result, much of the art of developing maintainable software lies in building out the refactoring tools we have available to us when we hit those limits, and in the case of Python, that means using features like functions to factor out request/response operations, generators to factor out a result series, classes to factor out structurally related data, context managers to separate out before/after structures, couroutines to separate out interactive agents, etc.