Loop better: A deeper look at iteration in Python

When we come to perform some actions over a sequence in Python, we use the for loop most of the time. The sequence is a general term, which can refer to a list, a tuple, a dictionary, a set, or a string, all of which can be used in a for loop in Python. Here’s an example of how we use the for loop, usually.

>>> students = ["John", "Mike", "Sandra", "Jennifer"]
>>> for student in students:
...     print(student)
... 
John
Mike
Sandra
Jennifer

Beyond this simple use case, there are several built-in functions that you can use together with the iteration of a sequence using the for loop. When used properly, these functions can make your code much cleaner.

1. items() and values()

Suppose we have a dictionary like the below.

>>> scores = {"John": 94, "Mike": 95, "Sandra": 98, "Jennifer": 95}

When you iterate this dictionary, the regular for loop will only retrieve the keys for the dictionary. In this case, it will only print out the name for each item. It functions the same as iterating the keys of the list.

>>> for score in scores:
...     print(score)
... 
Mike
John
Jennifer
Sandra

Instead, we can use the items() function, which will give us access to both the key and the value of each item.

>>> for score in scores.items():
...     print(score)
... 
('Mike', 95)
('John', 94)
('Jennifer', 95)
('Sandra', 98)

You can take a step further by naming the tuple’s items so that you can access both directly.

>>> for name, score in scores.items():
...     print("Student Name: " + name + ", Score: " + str(score))
... 
Student Name: Mike, Score: 95
Student Name: John, Score: 94
Student Name: Jennifer, Score: 95
Student Name: Sandra, Score: 98

Sometimes, if you’re only interested in the values of the dictionary, you can simply use the values() function.

>>> for score in scores.values():
...     print(score)
... 
95
94
95
98

2. enumerate()

Suppose we have a list like the below.

>>> grades = ["Freshman", "Sophomore", "Junior", "Senior"]

Sometimes, we want to access both the index and the item itself. In this case, you can use the enumerate() function, in which you pass the list as the parameter.

>>> for grade in enumerate(grades):
...     print(grade)
... 
(0, 'Freshman')
(1, 'Sophomore')
(2, 'Junior')
(3, 'Senior')

Similarly, you can access the index and the item separately if you refer to the tuple’s items. In addition, you can specify the enumerate() function’s start index, which is handy in our case.

>>> for year, name in enumerate(grades, start=1):
...     print("Year " + str(year) + ": " + name)
... 
Year 1: Freshman
Year 2: Sophomore
Year 3: Junior
Year 4: Senior

3. reversed()

Suppose we have a list like the below. This list shows the students who have arrived at the classroom in a temporal order.

>>> arrived_students = ["John", "Mike", "Sandra", "Jennifer"]

The teacher then wanted to check their homework, starting with the student who arrived at the latest time. So it can be done like this. We can simply call the reversed() function with the list.

>>> for student in reversed(arrived_students):
...     print(student)
... 
Jennifer
Sandra
Mike
John

One thing to note is that you want to differentiate the reversed() function from the reverse() function, with the latter reversing the order of a given list without returning the list itself. In other words, you can call arrived_students.reverse(), but you can’t iterate it directly by calling for student in arrived_students.reverse().

4. sorted()

Suppose we have a list like the below.

>>> students = ["John", "Mike", "Sandra", "Jennifer"]

The teacher wants to sort the students based on their names and perform some actions (e.g., ask a question). It can be done with the sorted() function by passing in the list of students as the parameter, which will generate the list with their names sorted in the ascending order. You can optionally set a boolean value to the reverse parameter to request the order by ascending or descending, like this: sorted(students, reverse=True).

>>> for student in sorted(students):
...     print(student)
... 
Jennifer
John
Mike
Sandra

What if the list’s items are dictionaries, like below?

>>> students = [{"name": "John", "id": 1}, {"name": "Mike", "id": 4}, {"name": "Sandra", "id": 2}, {"name": "Jennifer", "id": 3}]

Essentially, we’re sorting a list of dictionaries. This can be done by setting the key parameter using lambda in the sorted() function.

>>> for student in sorted(students, key = lambda i: i["id"], reverse=True):
...     print(student)
... 
{'name': 'Mike', 'id': 4}
{'name': 'Jennifer', 'id': 3}
{'name': 'Sandra', 'id': 2}
{'name': 'John', 'id': 1}

In the above example, we request the list be sorted by using the id key of the dictionary in the reverse order, which is clearly reflected by the printout.

If you want to sort with multiple keys, you’ll simply change the key parameter to something like key = lambda i: (i["id"], i["name"]).

5. filter()

Suppose that we still use the list of students below.

>>> students = [{"name": "John", "id": 1}, {"name": "Mike", "id": 4}, {"name": "Sandra", "id": 2}, {"name": "Jennifer", "id": 3}]

We only want to retrieve the information of the students with an even id number. This is we can conveniently get it done using the filter() function with the use of a lambda.

>>> for student in filter(lambda i: i["id"] % 2 == 0, students):
...     print(student)
... 
{'name': 'Mike', 'id': 4}
{'name': 'Sandra', 'id': 2}

6. zip()

Suppose that we have the following two lists.

names = ["John", "Mike", "Sandra", "Jennifer"]
ids = [1, 3, 2, 4]

Using the zip() function, we can conveniently use the information from both lists. Again, as before, you can always directly access the tuple’s items if you assign variable names to them, like for name, id in zip(names, ids).

>>> for student in zip(names, ids):
...     print(student)
... 
('John', 1)
('Mike', 3)
('Sandra', 2)
('Jennifer', 4)

Conclusions

The for loop is used very frequently in our code. By using the above functions in your for loop, you can potentially reduce your code length, making it easier and more fun to read!

Thank you for reading!

#python #developer #loop

Loop better: A deeper look at iteration in Python
13.70 GEEK