I have a list of tuples and single floats
v = [(1., 2., 3.), (4., 5.), 6., 7.]
Now I want to flatten it with the good old list comprehension
[item for sublist in v for item in sublist]
But an error occurs as single floats are not iterable. What is the most efficient way to unroll this mixed list? I tried to go through the list and use isininstance()
but once again, the list is not iterable.
EDIT: time comparisons so far
- numpy approach with hstack: 6.49 µs ± 100 ns per loop
- hasattr approach: 398 ns ± 2.11 ns per loop
- collections approach: 804 ns ± 1.27 ns per loop
CodePudding user response:
You can use hasattr
to check if the object is iterable (has a __iter__
method):
out = [item for sublist in v
for item in (sublist if hasattr(sublist, '__iter__') else [sublist])]
output: [1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
An alternative would be to use collections.abc
:
from collections.abc import Iterable
out = [item for sublist in v
for item in (sublist if isinstance(sublist, Iterable) else [sublist])]
Note that in both cases, strings are considered iterable, you might want to check for this specific case depending on your data.
CodePudding user response:
With numpy
you can use hstack():
v = [(1., 2., 3.), (4., 5.), 6., 7.]
v = np.hstack(v)
# Output
array([1., 2., 3., 4., 5., 6., 7.])
CodePudding user response:
The more-itertools package has a function specifically for this problem -
from more_itertools import collapse
v = [(1., 2., 3.), (4., 5.), 6., 7.]
print(list(collapse(v))
[1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0]
It works with strings too -
x = [('ab', 'cd'), 'e', ['f', 'gh']]
print(list(collapse(x))
['ab', 'cd', 'e', 'f', 'gh']