In Python programming, understanding and using iterables effectively is fundamental to proficient coding. Iterables are objects you can iterate or loop through. They support the sequential traversal of elements within them, making them a critical tool for accessing and manipulating elements in objects or data structures.
This article explores how to properly use Python iterables by focusing on the language’s built-in iterable data types: lists, tuples, dictionaries, strings, and sets. It also explains how to implement custom iterable types and perform advanced operations.
How To Loop Through Python Iterables
In Python, you can iterate through diverse iterable types using a for
loop. This enables you to navigate sequences and perform operations on individual items within lists, sets, and dictionaries.
The for
keyword in Python deviates from its utility in other object-oriented languages like Java. Python for
loops work more like iterator methods. Here are examples to demonstrate loop in iterables:
1. Looping Through a List
Lists are ordered collections of items, allowing for easy iteration using a for
loop.
fruits_list = ["Apple", "Mango", "Peach", "Orange", "Banana"]
for fruit in fruits_list:
print(fruit)
In the code above, fruit
acts as an iterator that the loop uses to traverse each list element while simultaneously printing them. The loop terminates after evaluating the last element in the list. The code above should give the following output:
Apple
Mango
Peach
Orange
Banana
2. Iterating Through a Tuple
Tuples are similar to lists but are immutable. You can iterate through them just like lists.
fruits_tuple = ("Apple", "Mango", "Peach", "Orange", "Banana")
for fruit in fruits_tuple:
print(fruit)
In this example, the for
loop iterates through the tuple, and in each iteration, the variable fruit
takes on the value of the current element in the tuple. The code should give the following output:
Apple
Mango
Peach
Orange
Banana
3. Looping Through Sets
Sets are unordered collections of unique elements. You can traverse through them using a for
loop.
fruits_set = {"Apple", "Mango", "Peach", "Orange", "Banana"}
for fruit in fruits_set:
print(fruit)
In this example, the for
loop iterates through the set. However, since sets are unordered, the order of iteration may not be the same as the order in which elements were defined in the set. In each iteration, the variable fruit
takes on the value of the current element in the set. The code should give an output similar to the following (the order may vary):
Mango
Banana
Peach
Apple
Orange
4. Iterating Through Strings
Strings are sequences of characters that you can loop through character by character.
string = "Kinsta"
for char in string:
print(char)
The code above iterates through the string “Kinsta” and prints each character on a new line. In each iteration, the variable char
takes on the value of the current character in the string. The code should give the following output:
K
i
n
s
t
a
5. Traversing a Dictionary
Using the for
loop is similar for lists, sets, tuples, and strings — but it’s different for dictionaries since they use key-value pairs to store items. Dictionaries present a unique case for looping, as you can iterate them using different approaches. Here are the different approaches you can use to traverse a Python dictionary:
- Iterating through keys:
countries_capital = { "USA": "Washington D.C.", "Australia": "Canberra", "France": "Paris", "Egypt": "Cairo", "Japan": "Tokyo" } for country in countries_capital.keys(): print(country)
The code above defines a dictionary called
countries_capital
, where country names are the keys, and their respective capitals are the values. Thefor
loop iterates through the keys of thecountries_capital
dictionary using thekeys()
method. This method returns a view object that displays a list of the keys in the dictionary, which makes it easy to loop through all the keys. In each iteration, the variablecountry
takes on the value of the current key. This code should give the following output:USA Australia France Egypt Japan
- Iterating through values:
countries_capital = { "USA": "Washington D.C.", "Australia": "Canberra", "France": "Paris", "Egypt": "Cairo", "Japan": "Tokyo" } for capital in countries_capital.values(): print(capital)
In the code above, the
for
iterates through the values of thecountries_capital
dictionary using thevalues()
method. This method returns a view object that displays a list of the values in the dictionary, making it easy to loop through all the values. In each iteration, the variablecapital
takes on the value of the current value in the list. This code should give the following output:Washington D.C. Canberra Paris Cairo Tokyo
- Iterating through key-value pairs:
countries_capital = { "USA": "Washington D.C.", "Australia": "Canberra", "France": "Paris", "Egypt": "Cairo", "Japan": "Tokyo" } for country, capital in countries_capital.items(): print(country, ":", capital)
The code above demonstrates how to iterate through both the keys and values of the
countries_capital
dictionary using theitems()
method. Theitems()
method returns a view object that displays a list of key-value tuples in the dictionary. In thefor
loop, each iteration unpacks a key-value pair from the current element in the list. The variablescountry
andcapital
are assigned the corresponding key and value, respectively. This code should give the following output:USA : Washington D.C. Australia : Canberra France : Paris Egypt : Cairo Japan : Tokyo
Advanced Iteration With enumerate() in Python
Another way to iterate over Python iterables while returning both the index and corresponding value of elements is through the enumerate()
function. Check out this example:
fruits_list = ["Apple", "Mango", "Peach", "Orange", "Banana"]
for index, fruit in enumerate(fruits_list):
print(fruit, index)
Here’s the output:
Apple 0
Mango 1
Peach 2
Orange 3
Banana 4
The enumerate
function also lets you specify the starting index, besides 0
, for the iteration operation. You can modify the example above as follows:
fruits_list = ["Apple", "Mango", "Peach", "Orange", "Banana"]
for index, fruit in enumerate(fruits_list, start = 2):
print(fruit, index)
Here’s the output:
Apple 2
Mango 3
Peach 4
Orange 5
Banana 6
Note that while this example specifies the starting index of the enumeration, enumerate
doesn’t apply a zero-based indexing to the iterable, as is the case with native lists. It simply appends the start value to the first element in the list all the way to the last one.
How To Implement Python Generators
Generators are special Python iterables that allow you to build generator objects without explicitly creating built-in types like lists, sets, or dictionaries. You can use generators to produce values as you go based on the generation logic.
Generators use the yield
statement to return the generated values one at a time. Here is an example of generator iterables:
def even_generator(n):
counter = 0
while counter <= n:
if counter % 2 == 0:
yield counter
counter += 1
for num in even_generator(20):
print(num)
The provided code defines an even_generator
function that produces a sequence of even numbers from 0
to a specified n
using the yield
statement. It utilizes a loop to generate these values and iterates through the result using the num
iterator, ensuring the evaluation of all values within the given range. This code outputs a list of even numbers from 0
to 20
, as shown below:
0
2
4
6
8
10
12
14
16
18
20
You can achieve even more conciseness when working with generator expressions. For example, you can design a generator function that also incorporates loop logic:
cube = (num ** 3 for num in range(1, 6))
for c in cube:
print(c)
Here, you assign the variable cube
to the outcome of a function that computes the cube of values in the range 1 to 6. It then loops through values within the specified range, outputting the computation’s outcome, one after the other. The output is as follows:
1
8
27
64
125
How To Build Custom Iterables
Python allows you to further customize iterable operations by using iterators. Iterator objects implement the iterator protocol and contain 2 methods: __iter__()
and __next__()
. The __iter__()
method returns an iterator object, while __next__()
returns the next value in an iterable container. Here’s an example of iterators in Python:
even_list = [2, 4, 6, 8, 10]
my_iterator = iter(even_list)
print(next(my_iterator)) # Prints 2
print(next(my_iterator)) # Prints 4
print(next(my_iterator)) # Prints 6
In this example, you use the iter()
method to create an iterator object (my_iterator
) from the list. To access each of the elements from the list, you wrap the iterator object with the next()
method. Since lists are ordered collections, the iterator returns the elements sequentially.
Custom iterators are ideal for operations involving large datasets that you can’t load into memory simultaneously. Since memory is expensive and prone to space constraints, you can use an iterator to process data elements individually without loading the entire dataset into memory.
Iterable Functions
Python uses functions to move through, manipulate, and inspect list elements. Some common list functions include:
sum
— Returns the sum of a given iterable, provided the collection is of numerical types (integers, floating point values, and complex numbers)any
— Returnstrue
if any of the iterable elements are true. Otherwise, it returnsfalse
.all
— Returnstrue
if all the iterable elements are true. Otherwise, it returnsfalse
.max
— Returns the maximum value of a given iterable collectionmin
— Returns the minimum value of a given iterable collectionlen
— Returns the length of a given iterableappend
— Adds a value to the end of a list iterable
The example below demonstrates these functions with a list:
even_list = [2, 4, 6, 8, 10]
print(sum(even_list))
print(any(even_list))
print(max(even_list))
print(min(even_list))
even_list.append(14) # Add 14 to the end of the list
print(even_list)
even_list.insert(0, 0) # Insert 0 and specified index [0]
print(even_list)
print(all(even_list)) # Return true only if ALL elements in the list are true
print(len(even_list)) # Print the size of the list
Here’s the output:
30
True
10
2
[2, 4, 6, 8, 10, 14]
[0, 2, 4, 6, 8, 10, 14]
False
7
In the example above, the append
function adds a single parameter (14
) to the end of the list. The insert
function allows specifying the index for insertion. Therefore, even_list.insert(0, 0)
inserts 0
at index [0]
.
The statement print(all(even_list))
returns false
because there is a 0
value in the list, interpreted as false
. Finally, print(len(even_list))
outputs the length of the iterable.
Advanced Iterable Operations
Python offers advanced features that promote conciseness in iterable operations. Listed below are some of them.
1. List Comprehensions
List comprehensions let you create new lists by applying a function to each element within existing lists. Here’s an example:
my_numbers = [11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
even_number_list = [num for num in my_numbers if num%2 == 0]
print(even_number_list)
In this code snippet, a list named my_numbers
is created with integers from 11
to 20
. The aim is to generate a new list, even_number_list
, containing only even integers. To achieve this, apply a list comprehension that returns an integer from my_numbers
only if that integer is even. The if
statement contains the logic that returns the even numbers.
Here’s the output:
[12, 14, 16, 18, 20]
2. Zip
Python’s zip()
function combines multiple iterables into tuples. Tuples store multiple values in one variable and are immutable. Here’s how to combine iterables using zip()
:
fruits = ["apple", "orange", "banana"]
rating = [1, 2, 3]
fruits_rating = zip(rating, fruits)
print(list(fruits_rating))
In this example, fruits_rating
pairs each rating with a fruit, creating a single iterable. The output is:
[(1, 'apple'), (2, 'orange'), (3, 'banana')]
This code acts as a rating system for different fruits, with the first list (fruits
) representing the fruits and the second list representing ratings on a scale from 1 to 3.
3. Filter
Another advanced function, filter, takes 2 arguments — a function and an iterable. It applies the function to each element in the iterable, then returns a new iterable containing only those elements for which the function returns a true
value. The following example filters a list of integer values within a given range to return only the even ones:
def is_even(n):
return n%2 == 0
nums_list = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
even_list = filter(is_even, nums_list)
print(list(even_list))
In the code above, you start by defining a function, is_even
, to compute an even number passed to it. Then, you create a list of integer values between 1 and 10 — nums_list
. Finally, you define a new list, even_list
, which uses the filter()
function to apply the user-defined method to the original list and return only the even list elements. Here’s the result:
[2, 4, 6, 8, 10]
4. Map
Like filter()
, Python’s map()
function takes an iterable and a function as arguments. But instead of returning elements from the initial iterable, it returns a new iterable containing the outcome of the function applied to each element from the first iterable. To square a list of integers, use the map()
function:
my_list = [2, 4, 6, 8, 10]
square_numbers = map(lambda x: x ** 2, my_list)
print(list(square_numbers))
In this code, x
is the iterator that traverses the list and transforms it via the square computation. The map()
function executes this operation by taking the original list as an argument alongside a mapping function. The output is as follows:
[4, 16, 36, 64, 100]
5. Sorted
The sorted
function sorts the elements of a given iterable in a specific order (ascending or descending) and returns it as a list. It takes in a maximum of 3 parameters — iterable
, reverse
(optional), and key
(optional). Then, reverse
defaults to False
, and if set to True
, the items are sorted in descending order. key
is a function that calculates a value to determine the sort order of the element in an iterable and it defaults to None
.
Here’s an example of how you can apply the sorted
function on various iterables:
# set
py_set = {'e', 'a', 'u', 'o', 'i'}
print(sorted(py_set, reverse=True))
# dictionary
py_dict = {'e': 1, 'a': 2, 'u': 3, 'o': 4, 'i': 5}
print(sorted(py_dict, reverse=True))
# frozen set
frozen_set = frozenset(('e', 'a', 'u', 'o', 'i'))
print(sorted(frozen_set, reverse=True))
# string
string = "kinsta"
print(sorted(string))
# list
py_list = ['a', 'e', 'i', 'o', 'u']
print(py_list)
This gives you the following output:
['u', 'o', 'i', 'e', 'a']
['u', 'o', 'i', 'e', 'a']
['u', 'o', 'i', 'e', 'a']
['a', 'i', 'k', 'n', 's', 't']
['a', 'e', 'i', 'o', 'u']
How To Handle Edge Cases and Errors in Iterables
Edge cases are common in many programming scenarios, and you should anticipate them in iterables. Let’s explore a few possibilities you may encounter.
1. Empty Iterables
You may run into issues when an iterable is empty, but some programming logic attempts to traverse it. You can address this programmatically to avoid inefficiencies. Here’s an example using an if not
statement to check whether a list is empty:
fruits_list=[]
if not fruits_list:
print("The list is empty")
This is the result:
The list is empty
2. Nested Iterables
Python also supports nested iterables, which are iterable objects containing other iterables within them. For example, you can have a list of food containing nested lists of food categories, such as meats, vegetables, and grains. Here’s how to model such a scenario using nested iterables:
food_list = [["kale", "broccoli", "ginger"], ["beef", "chicken", "tuna"], ["barley", "oats", "corn"]]
for inner_list in food_list:
for food in inner_list:
print(food)
In the code above, the food_list
variable contains three nested lists, representing different food categories. The outer loop (for inner_list in food_list:
) iterates through the primary list, and the inner loop (for food in inner_list:
) iterates through each nested list, printing each food item. The output is as follows:
kale
broccoli
ginger
beef
chicken
tuna
barley
oats
corn
3. Exception Handling
In Python, iterables also support exception-handling operations. For example, you may iterate over a list and encounter an IndexError
. This error means you’re trying to reference an element that exceeds the iterable’s bounds. Here’s how to handle such an exception using a try-except
block:
fruits_list = ["apple", "mango", "orange", "pear"]
try:
print(fruits_list[5])
except IndexError:
print("The index specified is out of range.")
In the code above, the fruits_list
iterable contains five elements mapped by indices 0
to 5
in the list collection. The try
phrase contains a print
function that attempts to display the value at index 5
of the iterable, which doesn’t exist. This executes the except
clause, returning the associated error message. The console returns the error:
The index specified is out of range.
Summary
Mastering iteration in Python is crucial for efficient and readable code. Understanding the various ways to iterate over different data structures, using comprehensions, generators, and leveraging built-in functions makes you a proficient Python programmer.
Whether working with lists, dictionaries, strings, or custom objects, knowing how to use and manipulate iterables is an indispensable skill in Python programming.
When you finish building your Python application and want to host online, try Kinsta’s Application Hosting. Your first $20 is on us!
Did we miss anything in this guide? Please share in the comment section below!