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. The for loop iterates through the keys of the countries_capital dictionary using the keys() 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 variable country 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 the countries_capital dictionary using the values() 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 variable capital 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 the items() method. The items() method returns a view object that displays a list of key-value tuples in the dictionary. In the for loop, each iteration unpacks a key-value pair from the current element in the list. The variables country and capital 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 — Returns true if any of the iterable elements are true. Otherwise, it returns false.
  • all — Returns true if all the iterable elements are true. Otherwise, it returns false.
  • max — Returns the maximum value of a given iterable collection
  • min — Returns the minimum value of a given iterable collection
  • len — Returns the length of a given iterable
  • append — 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!

Jeremy Holcombe Kinsta

Content & Marketing Editor at Kinsta, WordPress Web Developer, and Content Writer. Outside of all things WordPress, I enjoy the beach, golf, and movies. I also have tall people problems ;).