Say for example I have a structure that contains many sub-elements some of which are structures:
v = [1, 2, 3, [4, (5, 6)]]
How can I unpack these into a series of names that contain only the contents of the structures and not a structure?
Trying a, b, c, d, e, f = v
raises a ValueError
while using the starred expression would assign a structure to the names. How can I unpack them in order to get:
print(a, b, c, d, e, f)
to print:
1 2 3 4 5 6
Assignments are defined recursively, you need to use parentheses ()
and/or square brackets []
to enclose target names and match the nested structure of your iterable. In your case:
a, b, c, (d, (e, f)) = v
print(a, b, c, d, e, f)
1 2 3 4 5 6
Similarly, with no change in semantics, you could use []
to denote the structure:
a, b, c, [d, [e, f]] = v
print(a, b, c, d, e, f)
1 2 3 4 5 6
or, of course, mix them up.
Python will then unpack v
and assign the first 3 values normally, then unpack the contents of (d, (e, f))
and assign d
and then again unpack (e, f)
and do the same.
You can see this happening if you import the dis
module and disassembling the statement with dis.dis
:
dis.dis('a, b, c, (d, (e, f)) = v')
1 0 LOAD_NAME 0 (v)
3 UNPACK_SEQUENCE 4 # <- first unpack
6 STORE_NAME 1 (a)
9 STORE_NAME 2 (b)
12 STORE_NAME 3 (c)
15 UNPACK_SEQUENCE 2 # <- second unpack
18 STORE_NAME 4 (d)
21 UNPACK_SEQUENCE 2 # <- third unpack
24 STORE_NAME 5 (e)
27 STORE_NAME 6 (f)
30 LOAD_CONST 0 (None)
33 RETURN_VALUE
In general, to unpack arbitrarily nested structures, match the structure in the left side of the assignment (target-list):
v = [1, [2, [3, [4, 5]]]]
[a, [b, [c, [d, e]]]] = v
print(a, b, c, d, e)
1 2 3 4 5
the outer []
are, of course, unnecessary, just adding them to show that simply matching the structure suffices.
Another option you might consider is to flatten the structure and then assign it.
def flatten(container):
for i in container:
if isinstance(i, (list,tuple)):
for j in flatten(i):
yield j
else:
yield i
Then
a, b, c, d, e, f = flatten(v)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With