Python has touched the hearts of many software developers around the world, thanks to its utility and simplicity.
Python provides its users with a number of useful functions and data structures that make working with data easier, including tools used to efficiently loop through data - known as itertools.
This guide will show you how to use Python itertools to iterate through objects via:
- filter() - The
filter()function takes in a provided sequence or iterable along with a filtering criteria (a function or lambda). It then tests every element in the sequence to determine if the element fits the filtering criteria, returning only the elements that match that criteria.
- islice() - The
islice()function allows the user to loop through an iterable with a
stop, and returns a generator.
- map() - The
map()function creates an iterable map object that applies a specified transformation to every element in a chosen iterable.
- zip() - The
zip()function takes two iterable objects and returns a tuple of paired elements. The first item in both iterables is paired, the second item in both iterables is paired together, and so on.
We'll start by defining iterable objects and iteration functions and then proceed to look at some examples of the four iteration functions mentioned above.
Note: As of Python 3,
zip() are functionally equivalent to Python 2's
izip(). They all return iterators and don't require imports.
islice() wasn't ported into the built-in namespace of Python 3. You'll still have to import the
itertools module to use it.
What are Iterable Objects?
An iterable object/iterable can be defined as a container holding data that can be looped/iterated over. Iterable objects in Python include lists, sets, tuples and dictionaries.
Typically, when we work with iterable objects, we loop through them using basic tools like
for loops. We often ignore the features and tools a language may have that can help us with iterative tasks. Iteration tools offer efficient, standardized functions (similar to the functions you'd see in functional programming languages like Haskell) that integrate with other iterative functions to simplify iterative tasks down to just a few lines of code.
The filter() Function
filter() is a built-in function, and it allows us to take a group of iterable items and test if the elements within the iterable meet your specified filter criteria:
filter() returns a generator (
filter object) - we'll wrap it in a
list() to convert it back to a simple list. If we were to do filtering via
if statements, it'd look something like:
# Create a simple list numbered 0 to 10 number_list = [x for x in range(0,10)] # Will filter for even numbers even_numbers =  for number in number_list: if number%2 == 0: even_numbers.append(number) print(even_numbers)
This results in:
[0, 2, 4, 6, 8]
By contrast, we could've achieved this same result using
filter(), and passing in the same condition. If the condition is satisfied and
True is returned, it's not filtered out. If the condition isn't satisfied and
False is returned, the element of the iterable is filtered out.
This condition can be supplied either as an anonymous function -
lambda or a standalone function:
number_list = [x for x in range(0,10)] filtered_list = list(filter(lambda number: number % 2 == 0, number_list)) print(filtered_list)
When provided with a lambda - the
number is an element of the iterable we're currently filtering. For each
number, we check if it's divisible by 2. If so - it's included in the new output:
[0, 2, 4, 6, 8]
As long as the function returns
False, you can extract the function to stand alone and simply reference it here instead of using a
number_list = [x for x in range(0,10)] def is_even(number): return number%2==0 filtered_list = list(filter(is_even, number_list)) print(filtered_list)
Another function similar to
filterfalse(), can be found in
itertools. This is a counterpart of
filter() that returns the elements that don't satisfy the condition. After importing the function from
itertools we can use our past code and apply
filterfalse() to get just the odd numbers from the list:
from itertools import filterfalse number_list = [x for x in range(0,10)] filtered_list = list(filterfalse(lambda number: number % 2 == 0, number_list)) print(filtered_list)
This results in a filtered list of odd numbers:
[1, 3, 5, 7, 9]
Instead of an anonymous function, you can also use a standalone function here too:
from itertools import filterfalse number_list = [x for x in range(0,10)] def is_even(number): return number%2==0 filtered_list = list(filterfalse(is_even, number_list)) print(filtered_list)
The islice() Function
islice() function is part of the
itertools library, and it takes an iterable object and returns a segment from it, between the elements defined by the
end arguments given to the function:
itertools.islice(iterable, start, end)
islice() a string. Since this returns a generator, we'll wrap it in a list to contain the result as well. If you omit the
start argument - the function will slice until the mandatory provided
end argument. If both are provided, it'll slice between them and return that segment:
from itertools import islice old_string = "I need this, but not this" print(list(islice(old_string, 11)))
Here, we've sliced the
old_string from its start to the 11th element:
['I', ' ', 'n', 'e', 'e', 'd', ' ', 't', 'h', 'i', 's']
If we provide a
start argument, though, we can slice a specific segment out:
Free eBook: Git Essentials
Check out our hands-on, practical guide to learning Git, with best-practices, industry-accepted standards, and included cheat sheet. Stop Googling Git commands and actually learn it!
from itertools import islice old_string = "I need this, but not this" print(list(islice(old_string, 7, 11)))
['t', 'h', 'i', 's']
Usually, when working with iterables - we want to end up with an iterable, such as a list. Though, slicing is a common operation for strings as well, in which case, we typically want a string - not a list. Thankfully, it's easy to
join() the elements of the list back into a string:
print(''.join(list(islice(old_string, 0, 11))))
Here, we've joined each element to an empty string, which results in the sliced segment converted into a string:
I need this
The map() Function
map function takes an iterable object and a function that applies a transformation to all the items of the iterable:
map() function is included in Python's built-in functions, so there's no need to import anything.
map() offers the exact same functionality as
imap() from the
itertools module in Python 2.
Generally speaking - it's very useful when you'd like to perform batch-transformations on each element of an iterable. Each element maps to a transformed version of that element, or a result of another operation performed by or on that element.
Say, you'd like to raise every integer element to the power of 2:
number_list = [x for x in range(0,10)] numbers_powered =  for number in number_list: numbers_powered.append(number**2) print(numbers_powered)
This results in a sequence of:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Now, we can simplify this with a
print(list(map(lambda x: x**2, number_list)))
For each element in the
number_list iterable - the element is raised to the power of two, and put in a new list:
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
Of course, instead of an anonymous function, you can also define other functions instead:
number_list = [x for x in range(0,10)] def function(number): print("Performing transformation on number ", number) return number**2 print('Original list: ', number_list) mapped_list = list(map(function, number_list)) print('Transformed list: ', mapped_list)
This results in:
Original list: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] Performing transformation on number 0 Performing transformation on number 1 Performing transformation on number 2 Performing transformation on number 3 Performing transformation on number 4 Performing transformation on number 5 Performing transformation on number 6 Performing transformation on number 7 Performing transformation on number 8 Performing transformation on number 9 Transformed list: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
The zip() Function
zip() function accepts
0..n iterable objects and creates
0..n tuples containing the nth element of each of these iterables:
zip(iterable_1, iterable_2, iterable_3...)
It's a built-in function since Python 3, and offers the same functionality
izip() from the
itertools module offered in Python 2.
zip() together a list of names and a list of IDs, where the first name is zipped with the first ID, the second name is zipped with the second ID, et cetera:
names_list = ['Francis', 'Drake', 'Alexander', 'Robert', 'Elon'] id_list = ['001', '002', '003', '004', '005'] print(list(zip(names_list,id_list)))
This results in:
[('Francis', '001'), ('Drake', '002'), ('Alexander', '003'), ('Robert', '004'), ('Elon', '005')]
Note: If these iterables are not of the same shape, such as
names_list having 5 elements, and
id_list having 10 elements, only the first 5 would be mapped, while the rest of
id_list would be ignored. The longest common sequence will be mapped.
As usual, this returns a generator - so we've wrapped it in a
The same functionality and behavior is present with more than two iterables - you can provide an unbounded number of them, in fact:
names_list = ['Francis', 'Drake', 'Alexander', 'Robert', 'Elon'] last_name_list = ['Brown', 'Johnson', 'Tiedemann', 'Mann'] id_list = ['001', '002', '003', '004', '005'] zipped_list = list(zip(names_list, last_name_list, id_list)) print(zipped_list)
[('Francis', 'Brown', '001'), ('Drake', 'Johnson', '002'), ('Alexander', 'Tiedemann', '003'), ('Robert', 'Mann', '004')]
names_list is of length 5, while the other two iterables are of length 4 - the last element of
names_list doesn't have a pair.
This is a great tool to group related items that appear in different contexts.
Python comes with a number of built-in functions that help engineers easily and efficiently manipulate data, through a high-level API. Iteration is a very common operation - and Python's iteration tools are very handy for one-line, functional-style operations on elements.
In this guide, we've taken a look at the
islice() resids in the
itertools module, and isn't present in the built-in namespace - it's a type of function you'll commonly use for subsequencing other sequences, and is commonly used with the other functions highlighted in the guide.i