for i in range(len(sequence))
iterates over indices of sequence
.
i
takes values0
tolen(sequence)-1
- Time complexity: O(n) for sequence of length n
- Creates new int
i
each iteration - Prefer
for item in sequence
to iterate over values directly if index not needed
When to Use “for i in range(len(…))” in Python
The construct for i in range(len(sequence))
is a common pattern in Python for iterating over the indices of a sequence (like a list, tuple, or string). It’s often used when you need to access both the index and the value at that index during the iteration.
For example, let’s say you have a list of numbers and you want to print both the index and the value at that index:
numbers = [5, 8, 2, 1, 9]
for i in range(len(numbers)):
print(f"Index {i}: Value {numbers[i]}")
This will output:
Index 0: Value 5
Index 1: Value 8
Index 2: Value 2
Index 3: Value 1
Index 4: Value 9
In this case, using for i in range(len(numbers))
allows us to iterate over the indices of the numbers
list, and then use numbers[i]
to access the value at that index.
Sorting a List Based on Another List
One common use case for for i in range(len(...))
is when you need to sort one list based on the values in another list. Here’s an example:
names = ["Alice", "Bob", "Charlie", "David", "Eve"]
ages = [25, 32, 18, 47, 22]
# Sort the names list based on the ages list
sorted_names = [name for age, name in sorted(zip(ages, names))]
print(sorted_names)
# Output: ['Charlie', 'Eve', 'Alice', 'Bob', 'David']
In this example, we use the zip
function to create pairs of (age, name)
tuples, and then sort those tuples based on the age
value. We then use a list comprehension to extract just the name
values from the sorted list of tuples.
However, there’s an alternative way to achieve the same result using for i in range(len(...))
:
names = ["Alice", "Bob", "Charlie", "David", "Eve"]
ages = [25, 32, 18, 47, 22]
sorted_names = [None] * len(names)
for i in range(len(names)):
sorted_names[sorted(range(len(ages)), key=ages.__getitem__)[i]] = names[i]
print(sorted_names)
# Output: ['Charlie', 'Eve', 'Alice', 'Bob', 'David']
Here’s how this works:
- We create a new list
sorted_names
withNone
values, the same length asnames
. - We use
for i in range(len(names))
to iterate over the indices ofnames
. - Inside the loop, we use
sorted(range(len(ages)), key=ages.__getitem__)
to get a list of indices that would sort theages
list. - We use those sorted indices to assign the corresponding
names[i]
value to the correct position insorted_names
.
While this approach is more verbose and arguably less readable than the list comprehension version, it demonstrates how for i in range(len(...))
can be used to perform custom sorting operations.
Intentional Programming and Readability
As mentioned in one of the provided answers, using for i in range(len(...))
can sometimes improve code readability and express the intent of the code more clearly. This concept is known as “intentional programming.”
For example, let’s say you want to iterate over a list and perform some operation a fixed number of times, regardless of the values in the list. In this case, using for i in range(len(list))
can make the code more explicit:
my_list = [1, 2, 3, 4, 5]
for _ in range(len(my_list)):
# Perform some operation here
print("Operation performed")
Here, we use for _ in range(len(my_list))
to indicate that we want to perform the operation the same number of times as there are elements in my_list
, but we don’t actually need to access the values in my_list
.
Alternatively, you could use a simple for
loop with a counter variable:
my_list = [1, 2, 3, 4, 5]
counter = 0
while counter < len(my_list):
# Perform some operation here
print("Operation performed")
counter += 1
While this approach works, using for i in range(len(...))
can be more concise and easier to read, especially for Python developers who are familiar with this idiom.
When Not to Use “for i in range(len(…))”
While for i in range(len(...))
is a useful construct in certain situations, it’s generally not recommended to use it when iterating over the values of a sequence directly. In those cases, it’s better to use the standard for value in sequence
syntax:
# Good
my_list = [1, 2, 3, 4, 5]
for value in my_list:
print(value)
# Bad
my_list = [1, 2, 3, 4, 5]
for i in range(len(my_list)):
print(my_list[i])
The second example, while functionally correct, is more verbose and less readable than the first example. It also introduces the potential for off-by-one errors if the loop condition is not written correctly.
Code Examples
Here are a few more code examples demonstrating the use of for i in range(len(...))
in Python:
Reversing a List
my_list = [1, 2, 3, 4, 5]
reversed_list = [None] * len(my_list)
for i in range(len(my_list)):
reversed_list[len(my_list) - 1 - i] = my_list[i]
print(reversed_list)
# Output: [5, 4, 3, 2, 1]
In this example, we create a new list reversed_list
with None
values, the same length as my_list
. We then use for i in range(len(my_list))
to iterate over the indices of my_list
, and assign the values to the corresponding reverse indices in reversed_list
.
Removing Duplicate Values from a List
my_list = [1, 2, 3, 2, 4, 1, 5]
unique_list = []
for i in range(len(my_list)):
if my_list[i] not in unique_list:
unique_list.append(my_list[i])
print(unique_list)
# Output: [1, 2, 3, 4, 5]
Here, we use for i in range(len(my_list))
to iterate over the indices of my_list
. For each index i
, we check if the value my_list[i]
is already in the unique_list
. If not, we add it to unique_list
.
Swapping Values in a List
my_list = [1, 2, 3, 4, 5]
for i in range(len(my_list) // 2):
my_list[i], my_list[len(my_list) - 1 - i] = my_list[len(my_list) - 1 - i], my_list[i]
print(my_list)
# Output: [5, 4, 3, 2, 1]
In this example, we use for i in range(len(my_list) // 2)
to iterate over the first half of the indices in my_list
. For each index i
, we swap the value at index i
with the value at the corresponding index from the end of the list (len(my_list) - 1 - i
).
These examples demonstrate how for i in range(len(...))
can be used to perform various operations on lists in Python, such as reversing, removing duplicates, and swapping values.