Ranges, lists and new lists
range doesn't make a list. A range hands out its numbers one at a time, whenever a loop asks for the next one, so it never needs to hold them all. That's why printing a range shows just the call that made it, not its numbers:
hours = range(8, 13)
print(hours)
print(list(hours))
print(list(range(10, 0, -3)))
range(8, 13)
[8, 9, 10, 11, 12]
[10, 7, 4, 1]The function list turns a range into a real list with all its numbers. A for loop doesn't need that: it goes through a range just as well as through a list.
Building a new list
A common job is to make a new list from an old one. Start with an empty list and append to it in the loop. The new list can keep only some of the items:
def passed(scores: list) -> list:
result = []
for score in scores:
if score >= 50:
result.append(score)
return result
scores = [72, 35, 50, 90, 48]
print(passed(scores))
print(scores)
[72, 50, 90]
[72, 35, 50, 90, 48]or change each item on the way:
def half_price(prices: list) -> list:
result = []
for price in prices:
result.append(price / 2)
return result
print(half_price([10, 4, 30]))
[5.0, 2.0, 15.0]Either way, the original list stays as it was, and the function returns the new one.
When you need the index
Sometimes the item alone isn't enough: you need its index too, for example to compare it with the item next to it, or with the item at the same index in another list. Then go through the indexes with range(len(...)):
home = [2, 0, 3]
away = [1, 0, 4]
for i in range(len(home)):
print(f"Game {i + 1}: {home[i]}-{away[i]}")
Game 1: 2-1
Game 2: 0-0
Game 3: 3-4range(len(home)) gives the indexes 0, 1 and 2, and home[i] and away[i] are the items at the same index in the two lists.