Lesson 5.7
Loop over a list two ways
Part 5: Text, lists, stacks and queuesReading, about 5 min4 exercises in this lesson, in Python3 exercises in this lesson, in Java
Java answers can't run on Spine yet. You can still read Java, trace it, and put an answer's lines in order.
Two ways through a list
By the end of this you will be able to visit every value in a list by its index, or one value at a time, and choose the loop that fits the job.
By index
values = [3, 8, 5]
for i in range(len(values)):
print(str(i) + ": " + str(values[i]))public static void main(String[] args) {
int[] values = {3, 8, 5};
for (int i = 0; i < values.length; i++) {
System.out.println(
i + ": " + values[i]);
}
}When it runs, it prints:
0: 3 1: 8 2: 5
This is the loop that visits every character of a text value, used on a list. i goes from 0 to one less than the length, and values[i] is the value at that index.
One value at a time
values = [3, 8, 5]
for value in values:
print(value)public static void main(String[] args) {
int[] values = {3, 8, 5};
for (int value : values) {
System.out.println(value);
}
}When it runs, it prints:
3 8 5
Read the loop's first line as "for each value in values". The loop hands you the values in order, first to last. There is no index to get wrong and no way to run past the end.
Which one to use
Use the one-value loop when the values are all you need: printing them, adding them up, looking for one of them. Use the index loop when you need to know where you are in the list, or when you want to change the list.
Changing the list needs the index
values = [3, 8, 5]
for value in values:
value = value * 2
print(values[0])
for i in range(len(values)):
values[i] = values[i] * 2
print(values[0])public static void main(String[] args) {
int[] values = {3, 8, 5};
for (int value : values) {
value = value * 2;
}
System.out.println(values[0]);
for (int i = 0; i < values.length; i++) {
values[i] = values[i] * 2;
}
System.out.println(values[0]);
}When it runs, it prints:
3 6
In the first loop, value is a variable of its own that is given each value in turn. Giving value a new value changes only the variable, not the list, so the first value is still 3. The second loop writes to an index of the list, so the list itself changes.
A common mistake: changing the variable of a one-value loop and expecting the list to change. To change what is in the list, write to values[i].
Now try it yourself on the questions below.
Exercise 5.7.1 · Trace itTrace: double loop
Complete the trace table for this Python code. for x in nums gives x each value of nums in turn. [4]
Line 1: nums = [4, 1, 3]Line 2: for x in nums:Line 3, indented 1 level: x = x * 10Line 4: first = nums[0]Line 5: for i in range(len(nums)):Line 6, indented 1 level: nums[i] = nums[i] + 1Line 7: last = nums[2]Line 8: print(first + last)
Fill in one row each time a line changes x, first or last, or prints something. The table already has the right number of rows. In each row, write only what that line changes; you can leave the other cells empty or copy their values down. Write values the way Python shows them: 3 and 3.0 are different, and text goes in quotes. In the output column, write exactly what appears on screen, with no quotes around it.
| Row | x | first | last | output |
|---|---|---|---|---|
| 1 | ||||
| 2 | ||||
| 3 | ||||
| 4 | ||||
| 5 | ||||
| 6 | ||||
| 7 | ||||
| 8 | ||||
| 9 |
Exercise 5.7.1 · Trace itTrace: double loop (Java)
Complete the trace table for this Java code. for (int x : nums) gives x each value of nums in turn. size is the number of values. [4]
Line 1: int[] nums = {4, 1, 3};Line 2: for (int x : nums) {Line 3, indented 1 level: x = x * 10;Line 4: }Line 5: int first = nums[0];Line 6: int size = nums.length;Line 7: for (int i = 0; i < size; i++) {Line 8, indented 1 level: nums[i] = nums[i] + 1;Line 9: }Line 10: int last = nums[2];Line 11: System.out.println(first + last);
Fill in one row each time a line changes x, first or last, or prints something. The table already has the right number of rows. In each row, write only what that line changes; you can leave the other cells empty or copy their values down. Write values the way Java shows them: 3 and 3.0 are different, and text goes in quotes. In the output column, write exactly what appears on screen, with no quotes around it.
| Row | x | first | last | output |
|---|---|---|---|---|
| 1 | ||||
| 2 | ||||
| 3 | ||||
| 4 | ||||
| 5 | ||||
| 6 | ||||
| 7 | ||||
| 8 | ||||
| 9 |
Exercise 5.7.25.7.2 · Write itDouble every value
Write a function that doubles every value in a list (an array in Java) of whole numbers, and returns the list.
- Each value is replaced by two times itself, and stays at its index.
- The list can be empty. An empty list comes back empty.
- Every value is between -1000 and 1000, and there are at most 20 values.
Only the list your function returns is checked.
def double_all(values: list[int]) -> list[int]
Examples
Your function is tested on 8 cases: the 3 examples below, and 5 hidden ones that check the rules above.
- double_all([3, 8, 5]) should return [6, 16, 10]: three values, each doubled at its own index (rule 1)
- double_all([]) should return []: an empty list (rule 2)
- double_all([0, -4]) should return [0, -8]: zero stays zero, and a negative value doubles too (rule 1)
public static int[] doubleAll(int[] values)
Running Java here comes later. You can put this answer's lines in order instead. You can still write your Java answer (it stays while this page is open) and compare it with our worked solution. Or try this exercise in Python.Checking whether Java answers can run here.
Examples
Your function is tested on 8 cases: the 3 examples below, and 5 hidden ones that check the rules above.
- doubleAll(new int[]{3, 8, 5}) should return [6, 16, 10]: three values, each doubled at its own index (rule 1)
- doubleAll(new int[]{}) should return []: an empty list (rule 2)
- doubleAll(new int[]{0, -4}) should return [0, -8]: zero stays zero, and a negative value doubles too (rule 1)
Exercise 5.7.35.7.3 · Write itWhere it appears
Write a function that returns the indexes at which a target value appears in a list (an array in Java) of whole numbers.
- Return a list of indexes, in rising order.
- When the target does not appear, return an empty list.
- The list of values can be empty, and has at most 20 values. Every value, and the target, is between -1000 and 1000.
- In Java, return an
ArrayList<Integer>.
Only the list your function returns is checked.
def positions_of(values: list[int], target: int) -> list[int]
Examples
Your function is tested on 8 cases: the 3 examples below, and 5 hidden ones that check the rules above.
- positions_of([5, 3, 5, 8], 5) should return [0, 2]: the target appears twice, at indexes 0 and 2 (rule 1)
- positions_of([5, 3, 5, 8], 4) should return []: the target does not appear (rule 2)
- positions_of([7, 7, 7], 7) should return [0, 1, 2]: every value is the target, so every index is returned (rule 1)
public static ArrayList<Integer> positionsOf(int[] values, int target)
Running Java here comes later. You can put this answer's lines in order instead. You can still write your Java answer (it stays while this page is open) and compare it with our worked solution. Or try this exercise in Python.Checking whether Java answers can run here.
Examples
Your function is tested on 8 cases: the 3 examples below, and 5 hidden ones that check the rules above.
- positionsOf(new int[]{5, 3, 5, 8}, 5) should return [0, 2]: the target appears twice, at indexes 0 and 2 (rule 1)
- positionsOf(new int[]{5, 3, 5, 8}, 4) should return []: the target does not appear (rule 2)
- positionsOf(new int[]{7, 7, 7}, 7) should return [0, 1, 2]: every value is the target, so every index is returned (rule 1)
Exercise 5.7.4 · Trace itTrace: grades
Complete the trace table for this Python code. Then answer the question below the table. [3]
Line 1: scores = [45, 72, 90]Line 2: grades = []Line 3: for s in scores:Line 4, indented 1 level: if s >= 80:Line 5, indented 2 levels: grades.append("A")Line 6, indented 1 level: elif s >= 60:Line 7, indented 2 levels: grades.append("B")Line 8, indented 1 level: else:Line 9, indented 2 levels: grades.append("C")Line 10: print(grades)
Fill in one row each time a line changes s or grades, or prints something. The table already has the right number of rows. In each row, write only what that line changes; you can leave the other cells empty or copy their values down. Write values the way Python shows them: 3 and 3.0 are different, and text goes in quotes. In the output column, write exactly what appears on screen, with no quotes around it.
| Row | s | grades | output |
|---|---|---|---|
| 1 | |||
| 2 | |||
| 3 | |||
| 4 | |||
| 5 | |||
| 6 | |||
| 7 | |||
| 8 |