Hacker News new | ask | show | jobs
by nicwest 3426 days ago
could someone explain to me why

    >>> ranges = [range(i) for i in range(5)]
    >>> [*item for item in ranges]
    [0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
would be better than:

    >>> ranges = [range(i) for i in range(5)]
    >>> [item for subrange in ranges for item in subrange]
    [0, 0, 1, 0, 1, 2, 0, 1, 2, 3]
2 comments

To be honest, the second one I have a hard time parsing.

I would expect that ranges is on the end, but it is somewhere in the middle.

   [item for item in subrange for subrange in ranges] 
is clearer to me. Then I can scan from left to right. It would read like a pipeline.

Now I need to start in the middle (ranges), scan to the left (for subrange), then to to the end (for item in subrange) and then back to the beginning (item). Or something like that, it is hard to follow your own eye movements. :)

Note that I seldom use python and the * pattern is something I recognize from another language, so I am biased. I imagine a seasoned python dev has no problems with the second case.

Btw, does python let you overload those comprehensions? That would be nice.

Less verbose.

Also, what happens if you have even more nested lists you want to flatten?

Personally I think it should just be

    flatten(range(i) or i in range(5))
With flatten in the global namespace
Given that flatten is surprisingly tricky to get right, it really should be built-in. The naive recursive variant will crash python if you nest lists beyond the stack limit, which is very no bueno. A list that's nested 10,000 layers deep is not especially hard to create or store in memory, and a flatten implementation should be able to handle it without crashing the interpreter.

In fact, it's not a bad little programming exercise: making a flatten that performs well and never crashes because of stack overflow.

I've not tried, but you can probably get that by recursively mixing standard constructs and functools.chain.from_iterable().
You should try. It's harder than it seems.

(I mean, it's not the most challenging problem ever, but most programmers look at it and go "that's trivial, just do X!", and it's a bit trickier than that).