Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Selective flattening of a Python list

Suppose I have a list containing (among other things) sublists of different types:

[1, 2, [3, 4], {5, 6}]

that I'd like to flatten in a selective way, depending on the type of its elements (i.e. I'd like to only flatten sets, and leave the rest unflattened):

[1, 2, [3, 4], 5, 6]

My current solution is a function, but just for my intellectual curiosity, I wonder if it's possible to do it with a single list comprehension?

like image 879
cjauvin Avatar asked Dec 07 '25 09:12

cjauvin


2 Answers

List comprehensions aren't designed for flattening (since they don't have a way to combine the values corresponding to multiple input items).

While you can get around this with nested list comprehensions, this requires each element in your top level list to be iterable.

Honestly, just use a function for this. It's the cleanest way.

like image 106
Amber Avatar answered Dec 08 '25 21:12

Amber


Amber is probably right that a function is preferable for something like this. On the other hand, there's always room for a little variation. I'm assuming the nesting is never more than one level deep -- if it is ever more than one level deep, then you should definitely prefer a function for this. But if not, this is a potentially viable approach.

>>> from itertools import chain
>>> from collections import Set
>>> list(chain.from_iterable(x if isinstance(x, Set) else (x,) for x in l))
[1, 2, [3, 4], 5, 6]

The non-itertools way to do this would involve nested list comprehensions. Better to break that into two lines:

>>> packaged = (x if isinstance(x, collections.Set) else (x,) for x in l)
>>> [x for y in packaged for x in y]
[1, 2, [3, 4], 5, 6]

I don't have a strong intuition about whether either of these would be faster or slower than a straightforward function. These create lots of singleton tuples -- that's kind of a waste -- but they also happen at LC speed, which is usually pretty good.

like image 29
senderle Avatar answered Dec 08 '25 22:12

senderle



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!