B2.2.2 · Data structures
Arrays and Lists
A List is the guide’s array, the same "collection of values, one index each" idea, indexed from zero.
Explainer
Think of a class register: 30 students, one numbered seat each, one piece of data per seat. An array, a List in Python, is exactly that: one row of numbered slots, each holding one value.
An array (implemented in Python as a List) stores a fixed-type collection of values, each reached by a single index. IB CS 2027 answers are written in Python, and Python indexes from 0, not 1.
This is the single most common source of lost marks on this statement: not the concept of an array, but which number points to the first element. If you’re working across boards, the two conventions genuinely conflict:
There is no universal rule. It depends entirely on which syllabus (and which language) the question is written in. Always check which one you’re in before writing a loop bound.
Worked example
Constructing a List first, before reading from it
The statement's own command word is construct, not just read. Before indexing into a finished list, build one from scratch: start with a list of 7 zeros, one slot per day of the week, then use a loop to ask the user for each real reading, one index at a time.
# Start with 7 zeros, one slot per day, sized in advance temperatures = [0] * 7 # Fill each index in turn, from user input for day in range(7): temperatures[day] = int(input("Enter a temperature: "))
// Declare a fixed size upfront, arrays cannot grow in Java int[] temperatures = new int[7]; // Fill each index in turn, from user input Scanner input = new Scanner(System.in); for (int day = 0; day < 7; day++) { temperatures[day] = input.nextInt(); }
Java must declare its size upfront (new int[7]) and can never grow past it. Python's [0] * 7 is a convenience for pre-sizing a list the same way, but the list itself CAN still grow or shrink afterward, Python lists are not fixed-size the way real arrays are.
A week of temperatures, indexed from 0
That loop has now filled all seven slots. Here is the same temperatures list being read back, one value per day, Monday first. Because Python indexes from 0, Monday is temperatures[0], not temperatures[1].
Click a value to see its index.
temperatures[3] is Thursday’s value, 23: the 4th day, since index 0 is Monday.
# temperatures[0] is Monday: Python indexes from 0 temperatures = [18, 21, 19, 23, 17, 20, 22] # Thursday's temperature: the 4th value, at index 3 print(temperatures[3]) # Visit every day, printing its position AND its value for day in range(len(temperatures)): print("Day", day, "=", temperatures[day])
// temperatures[0] is Monday: Java arrays also index from 0 int[] temperatures = {18, 21, 19, 23, 17, 20, 22}; // Thursday's temperature: the 4th value, at index 3 System.out.println(temperatures[3]); // Visit every day, printing its position AND its value for (int day = 0; day < temperatures.length; day++) { System.out.println("Day " + day + " = " + temperatures[day]); }
What is len(temperatures)? It’s 7, the number of values stored, not a valid index. This is exactly where the off-by-one mistake happens: 7 values exist, but because counting starts at 0, the valid indices only go up to 6, not 7.
What does for day in range(len(temperatures)) do? range(7) produces the sequence 0, 1, 2, 3, 4, 5, 6, one number per valid index. The loop then runs its body once for each of those seven values in turn, with day holding the current one, so every element gets visited exactly once, first to last.
The guide’s current generator only produces Python. Java is shown here as a reference for schools teaching that track; both index from 0.
Explainer
Two-dimensional arrays and lists
One week of temperatures is a single row. Now track four weeks, not one: that’s a table, one row per week, one column per day. A 2D array (Java) or 2D list (Python) stores exactly that shape, and every element needs two indices to reach it, not one.
A two-dimensional array/list is a table of values, addressed by a row index and a column index together. weekly_temps[1][3] means: go to row 1 (the second week), then column 3 (Thursday) within that row. Row always comes first, column second.
# 4 weeks, 7 days each: a list of lists, one inner list per week weekly_temps = [[0] * 7 for week in range(4)] # Outer loop for weeks (rows), inner loop for days (columns) for week in range(4): for day in range(7): weekly_temps[week][day] = int(input("Enter a temperature: ")) # Week 2 (index 1), Thursday (index 3): row first, then column print(weekly_temps[1][3])
// 4 rows (weeks), 7 columns (days), both dimensions fixed upfront int[][] weeklyTemps = new int[4][7]; Scanner input = new Scanner(System.in); for (int week = 0; week < 4; week++) { for (int day = 0; day < 7; day++) { weeklyTemps[week][day] = input.nextInt(); } } // Week 2 (index 1), Thursday (index 3): row first, then column System.out.println(weeklyTemps[1][3]);
Two nested loops, always. The outer loop moves down the rows (weeks), the inner loop moves across the columns (days) within whichever row the outer loop is currently on.
A month of temperatures, indexed by row and column
That double loop has now filled all 28 cells. Here is the same weekly_temps table read back, row (week) first, column (day) second.
Click a cell to see both its indices.
weekly_temps[1][3] is Week 2, Thursday’s value, 25.
Markers report the most common 2D mistake as treating the structure like a 1D one: reaching for a single index, or looping with only one variable, when the data genuinely has rows AND columns. weekly_temps[3] is a whole week (a row, still a list), not one temperature. Getting to an actual number always needs both indices.
Explainer
Dynamic lists: add, remove, traverse
The week of temperatures above was sized in advance, 7 slots, fixed. But readings from a sensor arrive throughout the day, with no way to know in advance how many there’ll be, including a faulty spike that needs deleting once it’s spotted. That calls for a structure that can genuinely grow and shrink, not just be pre-sized: this is B2.2.1’s dynamic data structure, in practice.
# Starts empty: we don't know in advance how many readings today will bring readings = [] readings.append(18) # add: a new reading comes in readings.append(21) readings.append(97) # a faulty sensor spike readings.remove(97) # remove: deletes the VALUE 97, wherever it is # traverse: visit every reading that's left for reading in readings: print(reading)
// Java's arrays can't grow, so a dynamic collection needs ArrayList instead ArrayList<Integer> readings = new ArrayList<Integer>(); readings.add(18); // add: a new reading comes in readings.add(21); readings.add(97); // a faulty sensor spike readings.remove(Integer.valueOf(97)); // remove BY VALUE, see note below // traverse: visit every reading that's left for (int reading : readings) { System.out.println(reading); }
Java's remove() is overloaded, and it matters which one you call. readings.remove(97) removes whatever is sitting at index 97, not the value 97, and crashes here since there aren’t 97 readings. To remove the value itself, wrap it: readings.remove(Integer.valueOf(97)). Python's readings.remove(97) has no such ambiguity, lists only remove by value.
Python's list was always capable of this, append() and remove() work on any list, growing or shrinking it as needed. Java's plain array from the section above cannot: once declared with a size, it never changes, which is exactly why a genuinely dynamic collection in Java needs ArrayList instead.
Try it yourself
Run all three: 1D, 2D, and a dynamic list
The same three techniques from above, live and editable: construct then index a 1D list, build a 4-week 2D table, and grow/shrink a dynamic list of readings.
Running in offline fallback mode. The full Python engine couldn't load (blocked school network, or no internet), so this console switched automatically to a small hand-written engine. It supports list construction, indexing (including 2D), range(), and append()/remove(), exactly what this page needs, but it isn't full Python.
Check your understanding
In Python, temperatures = [18, 21, 19, 23, 17, 20, 22]. Which index gives Sunday’s value (22)?
Common mistake
B2.2.1 / B2.2.2RecurringMarkers reported two contrasting failure modes on array/List questions: candidates who used the wrong index, and separately, candidates who reached for a collection method where the question asked for direct array indexing instead. The strongest responses were the ones that indexed the array directly and correctly, without substituting a built-in collection method for the indexing the question actually wanted.
A related pattern shows up in definition questions: asked to describe what a collection is, weaker answers stayed too vague or general rather than giving the precise idea, a data structure that holds multiple elements, accessed by position.
On two-dimensional arrays specifically, markers report candidates overlooking boundaries and, most often, indexing with only ONE subscript where the structure genuinely needs two, one for the row and one for the column.
Answer frame that scores: state the index explicitly, in digits, matching zero-based counting. Never describe a position in words ("the fourth value") without also giving its number. On a 2D structure, always name both indices, row then column.
What this mistake looks like: asked for the value stored at index 3, a candidate writes temperatures.index(23), a collection method that searches for a value and returns its position, the exact opposite of what was asked (given a position, return its value).
What it should say: temperatures[3], direct indexing, since the question gave the position and wanted the value. Save .index() for the reverse question: given a value, find where it lives.
What a vague definition looks like: “A collection is a place where you keep data.” Technically not false, but too general to earn the mark: it doesn’t say multiple elements, or how they’re accessed.
What it should say: “A collection is a data structure that holds multiple elements, each accessed by its position.” Names the plurality and the access method, the two things a bare description usually misses.
What the 2D mistake looks like: asked for week 2's Thursday temperature, a candidate writes weekly_temps[3], one index, treating the whole table as if it were still a single row.
What it should say: weekly_temps[1][3], row 1 (week 2) then column 3 (Thursday). A 2D structure is never fully addressed by one number alone.
Revision questions
Past-paper style. Write an answer, then reveal the marking points and mark yourself.
[1]State the index of the first element in a Python List.
[2]Write a line of Python that outputs the last value in temperatures without hard-coding the number 6.
[3]A candidate writes temperatures[7] intending to print Sunday’s value. Explain the error and state the correction.
Marking points
评分要点
- temperatures has 7 elements, so its valid indices are 0 to 6; temperatures[7] is out of range and raises an IndexError at run time.
- Sunday is the last element, at index 6, so the correction is temperatures[6] (or temperatures[-1]).
- temperatures 有 7 个元素,所以有效索引是 0 到 6;temperatures[7] 越界,在运行时引发 IndexError。
- 星期日是最后一个元素,在索引 6,所以修正为 temperatures[6](或 temperatures[-1])。
Flashcards
Active recall for this statement’s key terms.
Keep this statement’s practice with you
Free account: unlock every revision question and flashcard for B2.2.2, and every other IB CS 2027 statement.