Unpacking Sequence in Python

Python allows unpacking of any sequence(iterable) into variables using a simple assignment operation. Unpacking can be done by assigning sequence(iterable) to comma separated variables . Let us take example of tuple and understand unpacking.

Example:

In the below example elements of tuple P are assigned to variable x and y.

#unpacking P into variable x and y
P=(100,200)
x,y=P
print(x)
print(y)

Output:

100
200

In the below example list language is unpacked into english, hindi, french and japanese variables.

#unpack the list into variables
language=["hello","namaste","Bonjour","Konnichiwa"]

english,hindi,french,japanese=language

print("english={}, hindi={}, french={}, japanese={}".format(english,hindi,french,japanese))

Output:

english=hello, hindi=namaste, french=Bonjour, japanese=Konnichiwa

The only requirement for sequence unpacking is number of variables and number of sequence elements should match. if there is mismatch in number of variables and sequence elements python raises ValueError exception.

P=(100,200)
x,y,z=P

Output:

ValueError: not enough values to unpack (expected 3, got 2)
P=(100,200,300)
x,y=P

Output:

ValueError: too many values to unpack (expected 2)

Unpacking Arbitrary Number of variables

Python * expression can be used to assign arbitrary number of elements to single variable. Arbitrary number of variables will be stored in the form of list.

Example

In the below example arbitrary number of valuess assigned to variable other. Arbitrary number of values are stored in the form of list.

language=("hello","namaste","Bonjour","Hola","Konnichiwa")

#assign first elements to english and remaining to other
english,*other=language
print("english ={}, other={}".format(english,other))

#assign last elements to japanese and remaining to other
*other,japanese=language
print("other ={}, japanese={}".format(other,japanese))

Output:

english =hello, other=['namaste', 'Bonjour', 'Hola', 'Konnichiwa']
other =['hello', 'namaste', 'Bonjour', 'Hola'], japanese=Konnichiwa

* expression can be used anywhere between the variables. Once values assigned to leading and trailing variables remaining values will be assigned to * expression variable.

Example

In the below example variable other is used in between variables.

language=("hello","namaste","Bonjour","Hola","Konnichiwa")

#assign in between arbitary elements to other
english,*other,japanese=language
print("english={}, other={}, japanese={}".format(english,other,japanese))

english,*other,spanish,japanese=language
print("english={}, other={}, spanish={}, japanese={}".format(english,other,spanish,japanese))

Output:

english=hello, other=['namaste', 'Bonjour', 'Hola'], japanese=Konnichiwa
english=hello, other=['namaste', 'Bonjour'], spanish=Hola, japanese=Konnichiwa

Unpacking selective elements

Throwaway variable _(underscore) can be used to select and discard elements during sequence unpack. _ acts as temporary variable for sequence unpack.

Example:

In the below example _ temporary variable is used in different positions to selectively select variables.

language=("hello","namaste","Bonjour","Hola","Konnichiwa")

#assign value to english hindi japanese discarding remaining
english,hindi,_,_,japanese=language
print("english={}, hindi={}, japanese={}".format(english,hindi,japanese))

#assign value to english and hindi
english,hindi,*_=language
print("english={}, hindi={}".format(english,hindi))

#assign value to english and japanese
english,*_,japanese=language
print("english={}, japanese={}".format(english,japanese))

#assign value to hindi and spanish
_,hindi,_,spanish,_=language
print("hindi={}, spanish={}".format(hindi,spanish))

Output:

english=hello, hindi=namaste, japanese=Konnichiwa
english=hello, hindi=namaste
english=hello, japanese=Konnichiwa
hindi=namaste, spanish=Hola

Nested Sequence Unpacking

Neasted sequence can be unpacked by placing variables inside appropriate brackets.

Example:

In the below example inner sequences are unpacked

#unpacking inner sequence
detective=(("Sherlok","Holmes"),("221 Baker Street","Marylebone","London"))
(firstname,lastname),(street,addr,city)=detective

print("first name={}, lastname={}".format(firstname,lastname))
print("street={}, addr={}, city={}".format(street,addr,city))

Output:

first name=Sherlok, lastname=Holmes
street=221 Baker Street, addr=Marylebone, city=London

_ can be used in unpacking inner sequences.

#_ can be used to unpack inner sequences
detective=(("Sherlok","Scott","Holmes"),("221 Baker Street","Marylebone","London"))
(firstname,_,lastname),_=detective
print("firstname={}, lastname={}".format(firstname,lastname))

(firstname,_,lastname),(*_,city)=detective
print("firstname={}, lastname={}, city={}".format(firstname,lastname,city))

Output:

firstname=Sherlok, lastname=Holmes
firstname=Sherlok, lastname=Holmes, city=London

Passing Unpacked sequence as function parameters

Let us consider a case where we need to pass elements of the list as an arguments to function. if we directly pass the list python will throw TypeError.

def func(a,b,c,d):
  print("a={} b={} c={} d={}".format(a,b,c,d))

x=(1,2,3,4)
func(x)

Output:

TypeError: func() missing 3 required positional arguments: 'b', 'c', and 'd'

* expression can be used to unpack the sequence and pass it as arguments to function.

def func(a,b,c,d):
  print("a={},  b={},  c={},  d={}".format(a,b,c,d))

#passing unpacked variable to function
x=(1,2,3,4)
func(*x)

y=[11,12,13,14]
func(*y)

z="ABCD"
func(*z)

Output:

a=1,  b=2,  c=3,  d=4
a=11,  b=12,  c=13,  d=14
a=A,  b=B,  c=C,  d=D

** expression can be used to unpack dictionary elements and pass it as keyword arguments to function.

def func(a,b,c,d):
  print("a={},  b={},  c={},  d={}".format(a,b,c,d))

#passing unpacked dictionary to function
x={'a':1,'b':2,'c':3,'d':4}
func(**x)

y={'a':"A",'b':"B",'c':"C",'d':"D"}
func(**y)

Output:

a=1,  b=2,  c=3,  d=4
a=A,  b=B,  c=C,  d=D

Unpacking Multiple sequences

Python 3.5 onwards as per pep-448 changes multiple sequences can be unpacked in single statement.

Example

In the below example multiple sequences are unpacked to create single sequence.

#unpacking multiple dictionaries into single
x={1:"one",2:"two"}
y={3:"three",4:"four"}
z={5:"five",6:"six",7:"seven"}

a={**x,**y,**z,8:"eight",9:"nine"}
print(a)

x=[0,1,2,3]
y=[4,5,6,7,8,9]
#unpcking multiple list to one
z=[*x,*y]
print(z)

x={1,2,3,4}
y={9,8,7}
#unpacking multiple sets to one
z={*x,*y}
print(z)

Output:

{1: 'one', 2: 'two', 3: 'three', 4: 'four', 5: 'five', 6: 'six', 7: 'seven', 8: 'eight', 9: 'nine'}
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
{1, 2, 3, 4, 7, 8, 9}

While unpacking multiple dictionaries if dictionaries have same key value of right most dictionary key will be considered.

#if two dictionaries have same key latest unpacked will be taken
#rightmost will be considered latest
x={"a":1,"b":8,"c":4}
y={"c":5,"d":3}
u={**x,**y}
v={**y,**x}
print(u)
print(v)

Output:

{'a': 1, 'b': 8, 'c': 5, 'd': 3}
{'c': 4, 'd': 3, 'a': 1, 'b': 8}

Python 3.5 also supports function call with multiple unpacked sequences.

#functions can be called by unpacking multiple sesquences
def func(a,b,c,d,e,f):
  print("a= {} b={} c={} d={} e={} f={}".format(a,b,c,d,e,f))

x=[1,2,3]
y=[4,5,6]
func(*x,*y)
func(*"ABC",*"DEF")

Output:

a= 1 b=2 c=3 d=4 e=5 f=6
a= A b=B c=C d=D e=E f=F

Multiple dictionaries can be unpacked and passed as keyword argument to function.

#Multiple dictionaries unpacked as passed as keyword argument
def func(a,b,c,d,e,f):
  print("a= {} b={} c={} d={} e={} f={}".format(a,b,c,d,e,f))
  
x={"a":1,"b":2,"c":3}
y={"d":4,"e":5,"f":6}
func(**x,**y)

Output:

a= 1 b=2 c=3 d=4 e=5 f=6

2 thoughts on “Unpacking Sequence in Python”

Leave a Comment

Your email address will not be published. Required fields are marked *