“Unzipping” Python 2

JBallin
3 min readMay 25, 2017

--

Python’s definition of zip isn’t straightforward, so I want to “unpack” it.

numbers = [1,2,3]
letters = 'abcd'
zip(numbers, letters)
# [(1, 'a'), (2, 'b'), (3, 'c')]

Input

Zero or more iterables [1] (ex. list, string, tuple, dictionary)

Output

1st tuple = (element_1 of numbers, element_1 of letters)
2nd tuple = (e_2
numbers, e_2 letters)

n-th tuple = (e_n
numbers, e_n letters)

  1. List of n tuples: n is the length of the shortest argument (input)
    - len(numbers) == 3 < len(letters) == 4 → short= 3 → return 3 tuples
  2. Length each tuple = # of args (tuple takes an element from each arg)
    - args = (numbers,letters); len(args) == 2 → tuple with 2 elements
  3. ith tuple = (element_i arg1, element_i arg2…, element_i argn)

Edge Cases

  • Empty String: len(str)= 0 = no tuples
  • Single String: len(str) == 2 tuples with len(args) == 1 element(s)
zip()
# []
zip('')
# []
zip('hi')
# [('h',), ('i',)]

Zip in Action!

Build a dictionary [2] out of two lists

keys = ["drink","band","food"]
values = ["La Croix", "Daft Punk", "Sushi"]
### ZIP
my_favorite = dict( zip(keys, values) )
my_favorite["drink"]
# 'La Croix'
### NO ZIP
my_faves = dict()
for i in range(len(keys)):
my_faves[keys[i]] = values[i]

zip is an elegant, clear, & concise solution

Traverse the elements of two iterables in parallel

nums = [0,1,2,3,4,5]
string = "sup"
### ZIP
for n, s in zip(nums, string):
print n, ":", s
# 0 : s
# 1 : u
# 2 : p
### NO ZIP
short_len = len(nums) if len(nums) < len(string) else len(string)
for i in range(short_len):
print nums[i], ":", str[i]

Print columns in a table

* [3] is called "unpacking": f(*[arg1,arg2,arg3]) == f(arg1, arg2, arg3)

student_grades = [
[ 'Morty' , 1 , "B" ],
[ 'Rick' , 4 , "A" ],
[ 'Jerry' , 3 , "M" ],
[ 'Kramer' , 0 , "F" ],
]
row_1 = student_grades[0]
print row_1
# ['Morty', 1, 'B']
columns = zip(*student_grades)
names = columns[0]
print names
# ('Morty', 'Rick', 'Jerry', 'Kramer')

Extra Credit: Unzipping

zip(*args) is called “unzipping” because it has the inverse effect of zip

numbers = (1,2,3)
letters = ('a','b','c')
zipped = zip(numbers, letters)
print zipped
# [(1, 'a'), (2, 'b'), (3, 'c')]
unzipped = zip(*zipped)
print unzipped
# [(1, 2, 3), ('a', 'b', 'c')]

unzipped: tuple_1 = e1 of each zipped tuple. tuple_2 = e2 of each zipped

zip is now another tool in our arsenal! We’re now better equipped for the next, programming battle!

Arrivederci,
J

Footnotes

  1. An object capable of returning its members one at a time (ex. list [1,2,3], string 'I like codin', tuple (1,2,3), dictionary {'a':1, 'b':2})
  2. {key1:value1, key2:value2...}
  3. “Unpacking” (*)
# foo - function, returns sum of two arguments
def foo(x,y):
return x + y
print foo(3,4)
# 7
numbers = [1,2]
print foo(numbers)
# TypeError: foo() takes exactly 2 arguments (1 given)
print foo(*numbers)
# 3

* took numbers (1 arg) and “unpacked” its’ 2 elements into 2 args

Imagine the list as a suitcase and the elements as pieces of clothing. You decide you want to look at each item of clothing individually on the bed — you have to UNPACK (*) the suitcase so that each item is now an individual object instead of being bundled in a list.

--

--