Home > Mobile >  Unpack a single element from a list of lists python
Unpack a single element from a list of lists python

Time:08-12

I have zipped some data into as following:

list1 = [1,33,3]
list2 = [2,44,23]
list3 = [[3,4,5,6],[3,4,5,3],[4,5,3,1]]
list4 = [4,34,4]

data = [list(x) for x in zip(list1, list2, list3, list4)]

However, list3 is a list of lists. So the output ended up being

[[1,2,[3,4,5,6],4],
 [33,44,[3,4,5,3],34], 
 [3,23,[4,5,3,1],4]]

I would like to unpack the list inside the lists like the following:

[[1,2,3,4,5,6,4],
 [33,44,3,4,5,3,34], 
 [3,23,4,5,3,1,4]]

What is the best way to do that in python?

Cheers

CodePudding user response:

If only two level-deep, you can try with first principles:

out = [
    [e for x in grp for e in (x if isinstance(x, list) else [x])]
    for grp in zip(list1, list2, list3, list4)
]

>>> out
[[1, 2, 3, 4, 5, 6, 4], [33, 44, 3, 4, 5, 3, 34], [3, 23, 4, 5, 3, 1, 4]]

CodePudding user response:

Exploring concepts

First, we have to know what we should do.

The problem is only because list3 is a nested list and this is causing us problems. To come up with a solution we have to think on how to turn list3 from a nested to a normal list.

To point out:

  • the shape of list3 is well-defined and it's always the same.
  • list3 is nested hence we have to think methods to flatten the list.

Finally I come up with 2 possible methods


Flattening list3

I would suggest to flatten list3, using itertools.chain.from_iterable.

chain.from_iterable(iterable)

Alternate constructor for chain(). Gets chained inputs from a single iterable argument that is evaluated lazily.

this can flatten a list of lists.

Here is a possible implementation:

import itertools
list1 = [1,33,3]
list2 = [2,44,23]
list3 = [[3,4,5,6],[3,4,5,3],[4,5,3,1]]
list4 = [4,34,4]
flat_list3 = itertools.chain.from_iterable(list3)
data = [list(x) for x in zip(list1, list2, list3, list4)]
>>> [[1,2,3,4,5,6,4],
     [33,44,3,4,5,3,34], 
     [3,23,4,5,3,1,4]]

Deep nested list flatten

NOTE: This possibility is slower and applicable for nested lists that aren't of a particular shape.

You could use the deepflatten with the map builtin function.

Here is the equivalent to the defined function and arguments.

deepflatten(iterable, depth=None, types=None, ignore=None)

From the docs:

Flatten an iterable with given depth.

>>> from iteration_utilities import deepflatten
>>> data = [[1, 2, [3, 4, 5, 6], 4], [33, 44, [3, 4, 5, 3], 34], [3, 23, [4, 5, 3, 1], 4]]
>>> list(map(lambda x:list(deepflatten(x)),data))
[[1, 2, 3, 4, 5, 6, 4], [33, 44, 3, 4, 5, 3, 34], [3, 23, 4, 5, 3, 1, 4]]

Useful links:

  1. SO(ans) how to find lenght of a list of lists
  2. make a flat list out of lists
  • Related