Traversal by Index
for i in range(len(marks)): — longer to write, and the only form that can do four things: change the list, say where an item is, compare an item with its neighbour, and read two lists at the same place. The first of those is new; a string could never be changed at all.
1Program 1 — five grace marks for everybody
Raise every mark in a list by 5, in the list itself.
# give every mark 5 grace marks, in the list itself
marks = [56, 91, 43, 78]
print('Before:', marks)
for i in range(len(marks)):
marks[i] = marks[i] + 5
print('After: ', marks)Before: [56, 91, 43, 78] After: [61, 96, 48, 83]
for i in range(len(marks)):len(marks) is 4, so range(4) hands out 0, 1, 2, 3 — exactly the valid positions. Positions start at 0 and range() leaves its stop out, and the two rules cancel.
marks[i] = marks[i] + 5Read the right-hand side first: fetch the item at position i and add 5. Then the = writes that answer back INTO position i. The list itself is different afterwards.
2Program 2 — replace, but only some of them
Every mark below 33 is to be recorded as 0.
# replace every failing mark with 0
marks = [72, 28, 88, 15, 54]
for i in range(len(marks)):
if marks[i] < 33:
marks[i] = 0
print(marks)[72, 0, 88, 0, 54]
Note what the if is testing: marks[i], the item, while the assignment writes to marks[i], the place. The same expression means “the value there” on the right of an = and “the box there” on the left. There is no else, and none is needed: an item that fails the test is simply left as it is, because nothing is being built.
3Program 3 — is the list in order?
Say whether a list is sorted, by checking every item against the one after it.
# is the list already in order?
numbers = [3, 8, 12, 12, 20]
sorted_so_far = True
for i in range(len(numbers) - 1):
if numbers[i] > numbers[i + 1]:
sorted_so_far = False
if sorted_so_far:
print('The list is in order')
else:
print('The list is not in order')The list is in order
The list is not in order
numbers[i + 1] must stop one early. range(len(numbers) - 1) — because the last position has nothing after it, and asking for it raises IndexError: list index out of range. This is not the off-by-one mistake; it is the correction for reaching forward. Reaching backwards with numbers[i - 1] costs the same round at the other end: the loop must start at 1.The test is > rather than >=, so the repeated 12 does not count as out of order — a sorted list is allowed equal neighbours. That single character decides whether [3, 12, 12, 20] passes.
4Program 4 — two lists, read together
One list holds names and another holds their marks, in the same order. Print each name with its mark.
# two lists, read at the same position
names = ['Asha', 'Ravi', 'Meera', 'Karan']
marks = [72, 65, 88, 91]
for i in range(len(names)):
print(names[i], 'scored', marks[i])Asha scored 72 Ravi scored 65 Meera scored 88 Karan scored 91
marks[i] raises IndexError on the last round — or worse, silently pairs the wrong mark with the wrong name if a value was inserted in the middle. A dictionary keeps the pairing in one place and cannot drift; parallel lists are what you use before you reach for one.5Program 5 — reverse a list in place
Reverse a list without reverse() and without building a second list — by swapping items from the two ends inwards.
# reverse a list in place, by swapping from both ends
numbers = [10, 20, 30, 40, 50]
print('Before:', numbers)
for i in range(len(numbers) // 2):
last = len(numbers) - 1 - i
temp = numbers[i]
numbers[i] = numbers[last]
numbers[last] = temp
print('After: ', numbers)Before: [10, 20, 30, 40, 50] After: [50, 40, 30, 20, 10]
for i in range(len(numbers) // 2):Half the length, floor-divided. Each round swaps a PAIR, so running the whole way would swap everything back and leave the list exactly as it started. With five items that is range(2) — and the middle item never needs to move.
last = len(numbers) - 1 - iThe partner of position i, counted from the other end: 0 pairs with 4, 1 pairs with 3. Naming it is what keeps the three swap lines readable.
temp = numbers[i]The third box, from the swap program in Sample Programs. Without it, the first assignment overwrites the value the second one needs and both places end up holding the same number.
range(len(numbers)) swaps every pair twice — once from each end — so the second swap undoes the first. No error, and the program looks like it did nothing, which is exactly what makes it hard to spot.Python has numbers.reverse(), which does this in place in one call, and numbers[::-1], which hands back a reversed copy. Know all three: the difference between the last two is whether the original changes, and that is a question papers ask directly.
6Recap
The same expression is a value on the right of the = and a place on the left. This is the only way a loop can change a list.
numbers[i + 1] means stopping at len - 1; numbers[i - 1] means starting at 1. Both errors land on the first or last round only.
Parallel lists agree by position and nothing enforces it — a dictionary is what you use when the pairing must not drift.
Three lines with a third box, and range(len // 2) — going the whole way swaps every pair twice and undoes itself.
- 1
Double every number in a list, in place.
Hint ·
numbers[i] = numbers[i] * 2— program 1 with a different sum. - 2
Replace every negative reading with 0, and count how many you replaced.
Hint · Program 2 with a counter beside the assignment, inside the same
if. - 3
Report every position where a list of temperatures rose from one day to the next.
Hint ·
temps[i + 1] > temps[i], and stop the loop one early. - 4
Given parallel lists of items and prices, print each line and the bill total.
Hint · One loop over the positions, a
print()and a running total inside it. - 5
Swap the first half of a list with the second half — for an even length only.
Hint · Pair position
iwithi + len(numbers) // 2, and loop over half the length.
Which line changes the list itself?
A loop compares numbers[i] with numbers[i + 1]. What must its range be?
A reverse-by-swapping program uses range(len(numbers)) instead of range(len(numbers) // 2). What happens?