Zip to list of tuples

Zipping and Unzipping Iterables in Python

How to use the zip[] function to zip and unzip iterable objects in Python

Luay Matalka

Nov 20, 2020·5 min read

Photo by Ilya Pavlov on Unsplash

Introduction

Lets say that we have two lists, one that includes first names, and the other includes last names. We would like to somehow combine the first names with the corresponding last names as tuples. In other words, we would like to combine elements from multiple iterables that have the same index together in a list of tuples:

list_1 = [Jane, John, Jennifer]
list_2 = [Doe, Williams, Smith]
Desired Output:
[['Jane', 'Doe'], ['John', 'Williams'], ['Jennifer', 'Smith']]

zip[] function

We can accomplish this with the zip[] function, which is a built-in python function. The zip[] function is named due to its analogous mechanism as physical zippers. When you zip something, you bring both sides together. And thats how the zip[] function works! It brings elements of the same index from multiple iterable objects together as elements of the same tuples.

zip[*iterables]

The zip[] function takes in iterables as arguments, such as lists, files, tuples, sets, etc. The zip[] function will then create an iterator that aggregates elements from each of the iterables passed in. In other words, it will return an iterator of tuples, where the i-th tuple will contain the i-th element from each of the iterables passed in. This iterator will stop once the shortest input iterable has been exhausted.

Using the zip[] function

Well, based on the above goal, we have two lists [which are iterable objects], and we would like to combine the same indexed elements from each of these lists together. Thus, we can use the zip[] function to accomplish this as follows:

first_names = [Jane, John, Jennifer]
last_names = [Doe, Williams, Smith]
full_names = list[zip[first_names, last_names]]print[full_names]
# [['Jane', 'Doe'], ['John', 'Williams'], ['Jennifer', 'Smith']]

Remember, the zip[] function returns an iterator. Thus, we need to use the list[] function that will use this returned iterator [or zip object] to create a list. In addition, as long as the iterables passed in are ordered [sequences], then the tuples will contain elements in the same left-to-right order of the arguments passed in the zip[] function.

Two Cool Functions To Know in Python

Learn how to make tables with tabulate and show progress bars with tqdm in Python

towardsdatascience.com

What if we have three iterable objects?

Lets say we have another list, ages, that contains the age of the corresponding individual in the other two lists, first_names and last_names. We would like to also include the ages in in the tuple with the first and last name. Well, as mentioned above, the zip[] function takes in any number of iterables.

first_names = ['Jane', 'John', 'Jennifer']
last_names = ['Doe', 'Williams', 'Smith']
ages = [20, 40, 30]
names_and_ages = list[zip[first_names, last_names, ages]]print[names_and_ages]
# [['Jane', 'Doe', 20], ['John', 'Williams', 40], ['Jennifer', 'Smith', 30]]

Notice how the names_and_ages contains tuples with n elements [the same number of arguments, or iterable objects, we passed in to the zip[] function].

Passing in one argument to zip[]

If we only pass in one iterable object to the zip[] function, then we will get a list of 1-item tuples as follows:

first_names = ['Jane', 'John', 'Jennifer']print[list[zip[first_names]]]
# [['Jane',], ['John',], ['Jennifer',]]

Iterables with unequal lengths

What if we pass in lists [or other iterable objects] of unequal lengths? In other words, lets say that our last_names list contains 1 more element than first_names. Well, as mentioned above, the iterator returned by the zip[] function will stop once the shortest input iterable has been exhausted. In other words, our list of tuples will only contain the elements from the indexes that are present in all the iterables passed in to the zip[] function. Thus, the remaining elements in the longer iterables will be ignored.

first_names = [Jane, John, Jennifer]
last_names = [Doe, Williams, Smith, 'Jones']
full_names = list[zip[first_names, last_names]]print[full_names]
# [['Jane', 'Doe'], ['John', 'Williams'], ['Jennifer', 'Smith']]

If the elements in the longer iterables are needed, then we can use the itertools.zip_longest[] [zip_longest[] function located in the itertools module] function instead of zip[]. It will continue until the longest iterable is exhausted, and will replace any missing values with the value passed in for the fillvalue argument [default is None].

Parallel Iteration of Iterables

We can use the zip[] function to iterate in parallel over multiple iterables. Since the zip[] function returns an iterator, we can use this zip object [the iterator it returns] in a for loop. And since with each iteration of this iterator a tuple is returned, we can unpack the elements of this tuple within the for loop:

first_names = ['Jane', 'John', 'Jennifer']
last_names = ['Doe', 'Williams', 'Smith']
for first, last in zip[first_names, last_names]:
print[first, last]
# Output:
Jane Doe
John Williams
Jennifer Smith

Or we can have three iterables:

first_names = [Jane, John, Jennifer]
last_names = [Doe, Williams, Smith]
ages = [20, 40, 30]
for first, last, age in zip[first_names, last_names, ages]:
print[f{first} {last} is {age} years old]
# Output:
Jane Doe is 20 years old
John Williams is 40 years old
Jennifer Smith is 30 years old

Another example of parallel iteration:

We have two lists: a list of revenues and a list of costs. We would like to make a new list, profits, that is the difference between the revenues and costs. We can accomplish this using parallel iteration:

revenue = [30000, 50000, 70000, 90000]
cost = [10000, 15000, 20000, 30000]
profit = []
total_profit = 0
for revenue, cost in zip[revenue, cost]:
profit.append[revenue cost]
total_profit += revenue cost
print[profit]
# [20000, 35000, 50000, 60000]
print[total_profit]
# 165000

How to Easily Create Tables in Python

How to use the tabulate function to create nicely-formatted tables in Python

towardsdatascience.com

Unzipping in python

Lets say that we have the following list of tuples:

first_and_last_names = [['Jane', 'Doe'], ['John', 'Williams'], ['Jennifer', 'Smith']]

And we want to separate the elements in these tuples into two separate lists. Well, since that is the opposite of zipping [bringing things together], it would be unzipping [taking things apart]. To unzip in python, we can use the unpacking operator * with the zip[] function as follows:

first_names, last_names = zip[*first_and_last_names]first_names = list[first_names]
last_names = list[last_names]
print[first_names]
# ['Jane', 'John', 'Jennifer']
print[last_names]
# ['Doe', 'Williams', 'Smith']

The unpacking operator * will unpack the first_and_last_names list of tuples into its tuples. These tuples will then be passed to the zip[] function, which will take these separate iterable objects [the tuples], and combines their same-indexed elements together into tuples, making two separate tuples. Lastly, through tuple unpacking, these separated tuples will be assigned to the first_names and last_names variables. We then use the list[] function to convert these tuples into lists.

For more on unpacking operators [* and **], iterables, iterators, and iteration, check out the following two blogs:

Unpacking Operators in Python

Using the * and ** unpacking operators in python

towardsdatascience.com

Iterables and Iterators in Python

Iterables, iterators, and iteration in Python

towardsdatascience.com

Conclusion

In this tutorial, we looked at how the zip[] function works in python. We learned how the zip[] function operates in different scenarios, such as with one iterable, or with iterables that have unequal lengths. We then saw how we can use the zip[] function to iterate over multiple iterable objects in parallel. And lastly, we learned how to use the unpacking operator * to unzip objects in python.

Video liên quan

Chủ Đề