loading...
Cover image for Python SnakeBytes: Unpacking

Python SnakeBytes: Unpacking

codemouse92 profile image Jason C. McDonald ・1 min read

Collections, and most other iterables, can be unpacked into individual names, by assigning the collection to a comma-separated list of names.

composers = ['Dvorak', 'Tian', 'Richter', 'Beethoven', 'Holst', 'Elgar']

first, second, third, fourth, fifth, sixth = composers
print(first)  # prints 'Dvorak'
print(second)  # prints 'Tian'
print(third)  # prints 'Richter'
print(fourth)  # prints 'Beethoven'
print(fifth)  # prints 'Holst'
print(sixth)  # prints 'Elgar'
Enter fullscreen mode Exit fullscreen mode

There must be enough names on the left side of the assignment operator to hold all the values. Otherwise, a ValueError is raised.

A single starred expression, a name preceded with an asterisk, may be used in the list of names to capture multiple values.

first, second, third, *rest = composers
print(first)  # prints 'Dvorak'
print(second)  # prints 'Tian'
print(third)  # prints 'Richter'
print(rest)  # prints ['Beethoven', 'Holst', 'Elgar']
Enter fullscreen mode Exit fullscreen mode

All of the non-starred names will be assigned to first, and the remainder placed in the starred name.

The name _ is conventionally used for values that are being ignored.

first, _, _, _, _, last = composers
print(first)  # prints 'Dvorak'
print(last)  # prints 'Elgar'
Enter fullscreen mode Exit fullscreen mode

Like any name, _ can also be starred:

first, *_, last = composers
print(first)  # prints 'Dvorak'
print(last)  # prints 'Elgar'
Enter fullscreen mode Exit fullscreen mode

Unpacking is also employed in for loops, generator expressions, and argument lists. Anywhere an iterable is being assigned, unpacking can be used.

CAUTION: Do not attempt to unpack an infinite iterator using starred expressions. It can cause the interpreter (or even the whole system) to lock up.

Discussion

pic
Editor guide
Collapse
vikasz profile image
Vikas Zingade

Unpacking is really cool. Will be helpful a lot for the application developers. The walrus operator on the other hand was unnecessary in 3.8

Collapse
codemouse92 profile image
Jason C. McDonald Author

I don't know that it was. It does simplify some conditional statements by moving the assignment into the comparison expression.

if value := will_this_return():
    print(f"Do something with {value}")

Without the walrus operator, we'd have to add additional code and complexity for no immediate benefit:

value = will_this_return()
if value:
    print(f"Do something with {value}")

That's a simplistic example, of course, but it demonstrates a situation that more robust code sometimes encounters.

I've learned not to dismiss a tool or feature as "unnecessary" just because I can't think of a use case myself; doing so would be quite presumptive on my part!

PEP 572 includes some notes by Tim Peters on which situations are well-suited to the walrus operator, and which are not.