Concepts / Array Indexing and Index Expressions

Array Indexing and Index Expressions

An array index can be an integer variable or an integer-valued expression, so the element accessed can change as the variable changes.

  • Programming

Predicting Before Reading the Mechanism

Imagine an array holding five stored values, and a loop whose counter starts at zero. The loop body runs once for each counter value and stops as soon as the counter reaches five. On each pass the body prints the element whose position matches the current counter value. Before you read further, try to predict what this program prints, and in what order. Making that prediction first will show you which parts of the mechanism you already understand and which parts need closer attention.

The rest of this article explains the mechanism behind that prediction. The central idea is that an array index does not have to be a fixed number written into the code. It can be held in an integer variable, or it can be any expression whose value is an integer. Because the variable can change while the written code stays the same, one line of code can reach different elements at different moments. That flexibility is one of the main reasons arrays are so useful.

Watching One Index Change

Think of the index variable as a pointer that moves through the positions of the array. Suppose the array holds the values 10, 20, 30, 40, and 50 at positions zero through four. If the variable i holds zero, the expression list[i] names the first position, which holds 10. If i then holds one, the same written text list[i] names the second position, which holds 20. The text list[i] never changes. Only the value of i changes, and that changed value redirects the access.

list[0]10list[1]20list[2]30list[3]40list[4]50
When the index variable goes from 0 to 1 to 2, which slot of the array does list[i] point to? The written expression stays the same while the element it selects changes.

The diagram uses invented values for illustration. The point to notice is that each index names exactly one stored value. When i holds zero, the expression selects the element at position zero. When i holds two, the same expression selects the element at position two. The expression is evaluated fresh each time it is used, so its result follows whatever the variable holds at that moment.

Index Expressions Choose the Position

An index is not limited to a bare variable. It can be any expression whose value is an integer. Python evaluates the expression inside the square brackets first, and the result of that evaluation decides which element is accessed. An expression such as i plus one simply produces the position one greater than i. Because the expression is computed before the element is read, it can combine the loop counter with other integers to reach a position that is offset from the current one.

Worked example

Evaluating an index expression

The array values are [10, 20, 30, 40, 50]. What does values[i + 1] select when i holds 2?

  1. 1
    Find the value of i

    The variable i holds 2.

  2. 2
    Evaluate the index expression

    i + 1 becomes 2 + 1, which is 3.

  3. 3
    Select the element

    values[3] names the element at position three, which holds 40.

Result

values[i + 1] selects 40 when i holds 2.

Walking Every Element with a Counting Loop

A for loop is the natural tool for visiting every element of an array, because its counter can serve as the array index itself. The loop variable starts at zero, the body runs once per value, and the variable increases after each pass. The continuation condition compares the variable with the array's length, and the loop continues only while that comparison holds. For printing every element of an array named values, the loop has this shape:

python
Output (expected)
10
20
30
40
50
Notes on the code
  • len(values) returns the array's length, which is 5 here.
  • range(len(values)) produces the counter values 0, 1, 2, 3, 4.
  • values[i] uses the counter as the index, so each pass reads the next position.
i = 0prints 10i = 1prints 20i = 2prints 30i = 3prints 40i = 4prints 50i = 5condition false, loop stopsincrease by 1increase by 1increase by 1increase by 1increase by 1
In what order does the for loop visit each element, and what are the first and last indices it touches? The counter runs 0 through 4 and stops before 5.

On the first pass the counter holds zero, so the body reads the value at position zero. On the second pass the counter holds one, and the body reads the value at position one. The pattern continues until the counter equals five. At that point the continuation condition is false and the loop stops. The body never runs with the counter at five, which is why the last printed element is the one at position four. The loop visits the indices in order, so the printed output follows the order of the positions in the array.

Mistakes with the Loop Boundary

  • Common mistake

    Using less than or equal to length as the loop condition

    What it looks like
    for i in range(len(values) + 1): print(values[i])
    Why it fails

    The valid positions run from zero through length minus one. When i reaches length, it names a position that does not exist in the array.

    Do this instead

    Keep the counter below the length, for example by using range(len(values)), which stops before the length value.

  • Common mistake

    Treating the length as the last valid index

    Why it fails

    The length is one more than the last valid index. An array of five items has length 5 but its last index is 4.

    Do this instead

    Remember that the last valid index is length minus one.

  • Common mistake

    Assuming the written expression always selects the same element

    What it looks like
    print(values[i]) prints 10, then 20, then 30 as i changes
    Why it fails

    The text values[i] stays fixed, but the value of i changes on each pass, so the selected element changes too.

    Do this instead

    Track the current value of the index variable before deciding which element is read.

Summing and Averaging Elements

Processing an array often means combining its elements rather than printing them. Suppose you have an array of double values and want its average. The plan has two stages. First, a loop adds every element into a running total that starts at zero. Second, the total is divided by the number of items in the array to produce the average. The division happens once, after the loop has finished.

python
Output (expected)
30.0
Notes on the code
  • total starts at zero, so it is ready to accumulate.
  • The loop body adds one element on each pass; the loop itself is the same counting pattern used for printing.
  • The division by len(values) happens once, after the loop ends.
total = 0before looptotal = 10after i = 0total = 30after i = 1total = 60after i = 2total = 100after i = 3total = 150after i = 4add values[0]add values[1]add values[2]add values[3]add values[4]
After each iteration, what are the running total and the counter? The final total of 150 divided by 5 items gives the average of 30.
Worked example

Tracing the sum and average

Trace the loop for the array [10.0, 20.0, 30.0, 40.0, 50.0] and find the average.

  1. 1
    Start the total

    total is set to 0.0 before the loop begins.

  2. 2
    Process the first elements

    Adding 10.0 gives 10.0, then adding 20.0 gives 30.0.

  3. 3
    Process the remaining elements

    Adding 30.0 gives 60.0, adding 40.0 gives 100.0, and adding 50.0 gives 150.0.

  4. 4
    Divide once

    After the loop, the total 150.0 is divided by len(values), which is 5.

Result

The average is 30.0.

Best practice

Initialize the accumulator to a starting value before the loop, update it inside the loop body on every pass, and perform the final division after the loop has finished. Keeping the division outside the loop means it is computed once rather than on every pass.

Predicting a Loop's Last Output

What do you think happens?

For the array [10, 20, 30, 40, 50] with the loop shown earlier, what is the last value printed?

  • 10

  • 40

  • 50

  • nothing is printed

Reveal answer
Answer:

50

The counter visits 0 through 4. On the pass where the counter is 4, the body reads values[4], which holds 50. The counter then reaches 5, the condition is false, and the loop stops.

MEDIUM

An array named scores holds the values 7, 3, 9, and 5. Trace a loop with a counter from 0 up to but not including len(scores) that prints scores[i] plus 1 on each pass. List the printed numbers in order, then state which index is read last and why.

Hints
  • The array has length 4, so the counter takes the values 0, 1, 2, and 3.
  • Add 1 to each element inside the body before printing.
  • The last index read is length minus one.

Key Takeaways

  • An array index can be an integer variable or any integer-valued expression, so the same written expression can select different elements as the variable changes.
  • A for loop whose counter runs from zero while the counter is less than the array's length visits every element once, in order from index zero upward.
  • The strict less-than stopping rule keeps the loop inside the array, because valid positions run from zero through length minus one.
  • To average an array, a loop adds each element into a running total that starts at zero, and the total is divided by the array length once after the loop.