2

I am aware that we can unpack items inside a list. For example this works:

mynestedlist = [[1,2],[3,4],[5,6],[7,8]]

for a,b in mynestedlist:
    print(a)
    print(b)

Results:

1
2
3
4
5
6
7
8

Is it possible to unpack a list that looks like this? I am looking for a solution where I can control the level of flattening, this question is not simply to arbitrary flatten an irregular list.

myotherlist = [[1,2,['A','B']],[3,4],[5,6],[7,8]]

When I try with the same approach, I receive:

ValueError: too many values to unpack (expected 2)

So I tried with the following approach:

for a,b,c in mynestedlist:
    print(a)
    print(b)
    print(c)

In this case I receive:

ValueError: not enough values to unpack (expected 3, got 2)

How do I unpack nested lists that may or may not vary in length without having to completely flatten all contained items?

Desired Results:

1
2
[A,B]
3
4
5
6
7
8
brazosFX
  • 342
  • 1
  • 11
  • @TomKarzes, I want just a vertical dump of everything, like the first successful output. I will update the question. Thx – brazosFX Aug 18 '19 at 01:31
  • 1
    Thanks for all the feedback. This is slightly different than those suggested flattening solutions because I want to control the level of flattening. Those solutions would help to get there, but I believe this really belongs as a stand-alone question along with the accepted solution. – brazosFX Aug 18 '19 at 02:03

3 Answers3

5

If you have:

mylist = [[1,2,['A','B']],[3,4],[5,6],[7,8]]

Then you can do a single-level traversal with a comprehension (without constructing any intermediate lists) with:

for v in (y for x in mylist for y in x):
    print(v)

This produces:

1
2
['A', 'B']
3
4
5
6
7
8

If you want to flatten it, you can create a generator that again doesn't construct any intermediate lists. Note that this will handle arbitrarily deep levels of nesting:

def walk(e):
    if type(e) == list:
        for v2 in e:
            for v3 in walk(v2):
                yield v3
    else:
        yield e

for v in walk(mylist):
    print(v)

This produces:

1
2
A
B
3
4
5
6
7
8
Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
2

You can make unpacking conditioned to the type of the element in the list.

def unpack(element):
    if isinstance(element, list):
        return element[0]
    return element

output_list_ = []
for item_ in input_list_:
    output_list_[input_list_.index(item_)] = (
        unpack(item_))
1737973
  • 159
  • 18
  • 42
2

Try to flat this using sum

myotherlist = [[1,2,['A','B']],[3,4],[5,6],[7,8]]


newlist = sum(myotherlist, [])

for elem in newlist:
     print(elem)

Output:

1
2
['A', 'B']
3
4
5
6
7
8

Let me know in the comment if you expected something else.

DennisLi
  • 3,915
  • 6
  • 30
  • 66