Lists can hold many values, and a program will often want to process each of those values to do useful work. The act of accessing each of the values in a list is called "traversal" or "iterating". In Python, you can easily use a "for" loop to traverse lists and tuples.

Simple List Traversal
Recall that you can iterate over each character in a string with a "for" loop and the "in" keyword.

phrase = "Look at me!"
for letter in phrase:
print(letter)
Copy
You can do exactly the same thing with lists or tuples! Let's set up a "for" loop to traverse a small list and print out each of the elements. We simply place the name of the list or tuple after the "in" keyword in the "for" statement. Inside the loop body, our loop variable will be automatically updated to hold one list value on each iteration.

Try It Now


This approach works well in many simple situations. However, there are some restrictions you should understand.

The traversal will always cover all list elements in order from start to end
You cannot update any values in the list (only read them from the list)
You do not have a numeric index, so won't understand which element you are processing on each iteration.
For example, the following program starts with a list that contains a series of "nobody" values. We then traverse the list and attempt to store "Gorilla Grodd" in each element by updating the loop variable. A second loop will print out the list contents to confirm the results. Does it work as intended?

Try It Now


Assigning a value to the loop variable inside a "for" loop does not change the underlying list element. It simply changes the value of the variable within that loop body.

Traversing Lists with a Numeric Index
How can we overcome the three limitations listed above? Recall that lists and tuples identify each element with a numeric index. With a numeric index, it is possible to directly access any element in any order and both read and update the value.

Example index values from 0 through 9 for highScores list

Let's rewrite our last example to use a "for" loop and a range to specify a numeric index. Remember that list index values start at 0 and go up to 1 less than the length of the list.

Try It Now


Our range starts at 0 and uses the len() function to get the number of items in the list. Remember, a range will go up to - but not include - the second number. So, with 5 elements in our list, this range will cover 0, 1, 2, 3, and 4. We use each index value inside the loop body, along with square brackets [], to directly update the value in each list element.

Using "range" to Process Part of a List
Your range parameters do not need to start at 0 and go up to 1 less than the list length. You can start or end at any valid index. For example, how would you process just the first half of a list? Your first range number should be 0, and the second range number would be half of the number of elements in the list.

first = 0
middle = int(len(superfriends) / 2)
for i in range(first, middle):
# loop body here
Copy
Notice that a division operation (dividing by 2) will produce a decimal (fractional) result when you have an odd number of elements. However, your range numbers must be integers, so we wrap the division with int() to force the result into an integer.

The following program demonstrates how to traverse both the first half and last half of a list.

Try It Now


Using "range" with a Step
The range keyword allows you to iterate between two numbers, and this iteration does not have to be sequential! You can add a 3rd parameter called a "step" to control how the number will change on each iteration.

In the example below, we add a "2" parameter at the end of the range. This range will start at 0, end at the length of the list minus 1, and go up by 2 each iteration. Can you predict the output before you run the code?

Try It Now


Try changing the step to 3 or 4 and observe the new results.

Using "range" for Backward Traversal
When using range with a step, you can make that step negative (e.g. -1) to go backward. However, you also need to switch the normal order and limits of the first two parameters. If your step is negative, then you want to start at the highest valid index (length-1) and end at the lowest valid index (0). Consider the following range:

range (len(superfriends) -1, -1, -1)
Copy
When going backward, to start at the last valid index, we set the first range parameter to the len() of the list minus 1.
The second range parameter must be one beyond where you want to stop. Since we want to iterate down through 0, which is the first valid index, we set the second parameter equal to -1. The iteration will therefore process down to index 0 and stop when it reaches -1.
The third range parameter is just our backward step, -1. Each time through the loop, the index will be reduced by 1.
We've put this all together in another example that will traverse our list backward. Try it and verify the results. You can change the step to -2 or other negative values to take bigger steps backward on each iteration.

Try It Now


As you can see, the range is very flexible! Any time you want to traverse a list and skip some elements, process part of the list, or traverse the list backwards, just set up a numeric range to produce your desired index values.

Example Algorithms
Study the example program below. The program will iterate over the list, examining the value at every index. All even values are summed together and all odd values are summed together. Can you predict the output before you run the program?

Try It Now


Python also has built-in min() and max() algorithms that will find the minimum or maximum value in a list.

Try It Now


With these useful building blocks - iteration over all or part of a list, the ability to process elements in the list in useful ways, and built-in Python functions that operate on lists - you can create more complex algorithms!

1. How do you set up a simple "for" loop to iterate over an entire list or tuple? What goes after the "in" keyword?
2. What are three limitations of a simple "for" loop when iterating over a list?
3. What are the smallest and largest valid numeric index values for a list?
4. How do you use a range() to iterate over a list using a numeric index?
5. How do you use a range() to iterate over part of a list?
6. What is the meaning of the 3rd, optional "step" parameter in the range()? How would you set the "step" to skip every other element?
7. When you set a negative step in the range, what must you also do to the first two parameters?

1. To set up a simple "for" loop to iterate over an entire list or tuple, you would write "for [variable] in [list or tuple]" where [variable] is the loop variable that represents each element in the list or tuple.

2. The three limitations of a simple "for" loop when iterating over a list are:
- The traversal will always cover all list elements in order from start to end.
- You cannot update any values in the list, only read them.
- You do not have a numeric index to understand which element you are processing on each iteration.

3. The smallest valid numeric index for a list is 0, representing the first element, and the largest valid numeric index is the length of the list minus 1, representing the last element.

4. To iterate over a list using a numeric index, you can use a range with the length of the list as the upper limit. The range starts at 0 and goes up to (but does not include) the length of the list. The index value can be used to access the elements of the list.

5. To iterate over part of a list, you can specify the desired range of indexes in the range() function by providing the starting and ending index values. For example, to iterate over the first half of a list, the first range number would be 0 and the second range number would be half of the number of elements in the list.

6. The 3rd, optional "step" parameter in the range() determines the increment or decrement between each iteration. By setting the "step" to 2, you can skip every other element in the range. For example, range(0, 10, 2) would iterate over 0, 2, 4, 6, and 8.

7. When setting a negative step in the range, you need to switch the order of the first two parameters and set the second parameter to -1. This is because the first parameter represents the starting index (highest valid index) and the second parameter represents the ending index (one beyond the desired range). The negative step allows for backward traversal through the list.

Make it shorter.

1. To iterate over a list or tuple: "for [variable] in [list or tuple]"

2. Limitations of a simple loop on a list: traversal covers all elements in order, cannot update values in the list, no numeric index

3. Smallest and largest valid indices for a list: 0 to length-1

4. Using range() to iterate over a list with a numeric index: "for i in range(len([list]))"

5. Using range() to iterate over part of a list: "for i in range([start index], [end index])"

6. Meaning of the 3rd "step" parameter in range(): controls increment or decrement; setting the step to 2 skips every other element

7. When using a negative step in range(), switch order of first two parameters and set second parameter to -1.