This question already has an answer here:
If I have sequence of sequences (maybe a list of tuples) I can use itertools.chain() to flatten it. But sometimes I feel like I would rather write it as a comprehension. I just can't figure out how to do it. Here's a very construed case:
Let's say I want to swap the elements of every pair in a sequence. I use a string as a sequence here:
>>> from itertools import chain
>>> seq = '012345'
>>> swapped_pairs = zip(seq[1::2], seq[::2])
>>> swapped_pairs
[('1', '0'), ('3', '2'), ('5', '4')]
>>> "".join(chain(*swapped_pairs))
'103254'
I use zip on the even and odd slices of the sequence to swap the pairs. But I end up with a list of tuples that now need to be flattened. So I use chain(). Is there a way I could express it with a comprehension instead?
If you want to post your own solution to the basic problem of swapping elements of the pairs, go ahead, I'll up-vote anything that teaches me something new. But I will only mark as accepted an answer that is targeted on my question, even if the answer is "No, you can't.".
With a comprehension? Well...
Or, to be agnostic about the type of inner sequences (as long as they are all the same):
Quickest I've found is to start with an empty array and extend it:
This is over twice as fast for the example in Alex Martelli's attempt on: Making a flat list out of list of lists in Python
I came up with this because I had a hunch that behind the scenes, extend would allocate the right amount of memory for the list, and probably uses some low-level code to move items in. I have no idea if this is true, but who cares, it is faster.
By the way, it's only a linear speedup:
You can also use the
map(results.extend, a)
, but this is slower as it is building its own list of Nones.It also gives you some of the benefits of not using functional programming. i.e.
By the way, probably best to avoid list comprehensions. Small ones aren't too bad, but in general list comprehensions don't actually save you much typing, but are often harder to understand and very hard to change or refactor (ever seen a three level list comprehension?). Google coding guidelines advise against them except in simple cases. My opinion is that they are only useful in 'throw-away' code, i.e. code where the author doesn't care about readability, or code that is known to never require future maintenance.
Compare these two ways of writing the same thing:
with this:
YMMV, but the first one stopped me in my tracks and I had to think about it. In the second the nesting is made obvious from the indentation.
You could use reduce to achive your goal:
This return a tuple instead of a list because the elements in your original list are tuples that get concatenated. But you can easily build a list from that and the join method accepts tuples, too.
A list comprehension is, by the way, not the right tool for that. Basically a list comprehension builds a new list by describing how the elements of this list should look like. You want to reduce a list of elements to only one value.