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
)
- List of
n
tuples:n
is the length of the shortest argument (input)
-len(numbers) == 3
<len(letters) == 4
→ short= 3 → return 3 tuples - Length each tuple = # of args (tuple takes an element from each arg)
-args = (numbers,letters); len(args) == 2
→ tuple with 2 elements i
th 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 withlen(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
- 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}
) {key1:value1, key2:value2...}
- “Unpacking” (
*
)
# foo - function, returns sum of two arguments
def foo(x,y):
return x + yprint foo(3,4)
# 7numbers = [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.