I would like to flatten a list but keep NaN
s. The following base code works when there are no NaN
s:
JavaScript
x
4
1
l = [[1], [2, 3, 4], [5]]
2
[item for sublist in l for item in sublist]
3
> [1, 2, 3, 4, 5]
4
Now if I have the following case it will break:
JavaScript
1
5
1
import numpy as np
2
l = [[1], [2, 3, 4], np.nan, [5]]
3
[item for sublist in l for item in sublist]
4
> TypeError: 'float' object is not iterable
5
which makes sense, but I need this border case to be handled and I’m not sure how to add the special case condition in the list comprehension above. How can I modify such comprehension to cover such case?
The expected output is:
JavaScript
1
2
1
[1, 2, 3, 4, np.nan, 5]
2
Advertisement
Answer
I would check to see if the sublist is iterable. If not then wrap it in a tuple to then be flattened:
JavaScript
1
8
1
import numpy as np
2
3
l = [[1], [2, 3, 4], np.nan, [5]]
4
5
[item for sublist in l for item in (sublist if hasattr(sublist, "__iter__") else [sublist])]
6
7
>>> [1, 2, 3, 4, nan, 5]
8
Using chain
from itertools
would make it a bit cleaner:
JavaScript
1
5
1
from itertools import chain
2
3
list(chain(*(sublist if hasattr(sublist, "__iter__") else (sublist, ) for sublist in l)))
4
>>> [1, 2, 3, 4, nan, 5]
5