Concepts / Copying Arrays Element by Element

Copying Arrays Element by Element

Assigning one array variable to another copies the reference, so both variables refer to the same array object.

  • Programming

A Surprise from a Simple Assignment

Assignment is one of the first things you learn in programming, and it usually feels simple. When an integer is assigned to a second variable, the second variable receives its own independent value. Changing one later never touches the other. Many learners carry this picture straight over to arrays, and that is where surprises begin.

The belief goes something like this: assigning one array variable to another gives you a duplicate array, so each variable now owns a separate collection of elements. This belief feels reasonable, and it is the single most common source of confusion when array code produces a value nobody expected. The belief is wrong for arrays. This article shows exactly what happens instead, so that you can look at an assignment line, know what it did, and predict the consequences for every later read and write.

What do you think happens?

Before reading on, commit to a prediction. After b = a and then b[0] = 99, what does print(a[0]) show: 10, 99, or an error?

  • 10

  • 99

  • an error

Reveal answer
Answer:

99

Both names refer to the same array object, so the write through b is visible when a is read. Assigning one array variable to another does not duplicate the elements.

Two Names, One Cabinet

Think of two sticky notes that both point at the same filing cabinet. Writing on the cabinet through either note changes what anyone sees inside it, and nothing about the cabinet is duplicated when you add a second note. The variable names in an array assignment behave like those sticky notes. They are labels attached to one shared object.

The diagram below shows the structure that an assignment creates. There are two variable names and one array object. The count of array objects is the important number. It stays at one, because the assignment never built a second one. Any read or write through either name reaches the same set of elements.

avariable namearray object10, 20, 30bvariable namerefers torefers to
After b = a, where do a and b point, and why is there only one array?

Once you hold this picture, the behavior of the assignment follows directly rather than feeling like an exception. The question to ask about any array variable is not what elements it owns, but which array object it currently names.

What the Assignment Line Actually Does

Definition

Assigning one array variable to another copies the reference, so both variables refer to the same array object.

The assignment statement has a precise effect that is easy to state. It takes the reference value stored in the right-hand variable and stores that same reference value in the left-hand variable. The left-hand variable becomes a second name for the array the right-hand variable already named. No element is moved, no element is duplicated, and no new array is allocated by that line.

python
Output (expected)
99
Notes on the code
  • Line 1 creates one array and gives it the name a. A Python list stands in for the array in this example.
  • Line 2 copies the reference from a into b. No elements are copied.
  • Line 3 writes through the name b, but it changes the single shared array.
  • Line 4 reads through the name a and sees the change made through b.
Before
a = [10, 20, 30]
b = a

Two names, one array: a and b both name the array holding 10, 20, 30.

After
a = [10, 20, 30]
b = a
b[0] = 99

The same single array now holds 99, 20, 30. Reading a[0] or b[0] gives 99.

shared array10, 20, 30shared array99, 20, 30b[0] = 99
If b[0] is changed through b, what does the shared array look like before and after, and what does a see?

The before and after views show a single array. The write changed one element of that array, and both names see it, because both names lead to the same object. The diagram has no second array to update.

Tracing a Change Through Two Names

Tracing means following each statement in order and recording what every variable names after that statement runs. The sequence diagram below does this for a short program. Each arrow is one statement that touches the array or a variable.

variable avariable barray objecta = [4, 7, 9] creates the arrayb = a copies the referencebackup[2] = 0 writes 0scores[1] = 5 writes 5
In which line does the shared value first change, and what does each variable see afterwards?
Worked example

Finding the line where the unexpected value appears

A program is run with these lines. The programmer expected backup[1] to still be 7. Which line first makes it different, and what do the final prints show?

scores = [4, 7, 9]
backup = scores
backup[2] = 0
scores[1] = 5
print(backup[1])
print(scores[2])
  1. 1
    Line 1

    scores names a new array holding 4, 7, 9. Nothing else exists yet.

  2. 2
    Line 2

    backup receives the reference from scores. Both names now refer to the same array. No elements were copied, so backup does not hold its own independent 4, 7, 9.

  3. 3
    Line 3

    backup[2] = 0 changes the shared array. Index 2 now holds 0 and both names see it. This line changes index 2, not index 1, so it is not the cause of the surprise about index 1.

  4. 4
    Line 4

    scores[1] = 5 changes index 1 of the shared array from 7 to 5. This is the first line where the value the programmer expected to see is altered.

  5. 5
    Line 5

    print(backup[1]) reads index 1 through backup. The shared array holds 5 there, so 5 is printed.

  6. 6
    Line 6

    print(scores[2]) reads index 2 through scores. The write from line 3 is visible, so 0 is printed.

Result

The unexpected value first appears at line 4, where scores[1] = 5 changes the shared array. The output is 5 followed by 0.

Null Array Variables

A variable that holds a reference can also hold null, which means it refers to no array at all. The same reference-copying rule applies here. If the right-hand variable is null, the left-hand variable also becomes null after the assignment. The two variables still agree about what they refer to, which is nothing.

python
Notes on the code
  • Line 1 gives a the null value, meaning it refers to no array.
  • Line 2 copies that null reference into b, so b also refers to no array.
  • Line 3 confirms that b refers to nothing, and prints True.
  • Line 4 tries to read an element through a null reference. There is no array to read from, so this raises an error rather than returning a value.

Making a True Copy

Because assignment does not duplicate elements, an independent copy requires explicitly creating a new array and copying the values. A common approach is to create a new empty array and copy each value across with a loop. After the loop, the two names refer to two different array objects that happen to hold the same values at that moment.

python
Output (expected)
10
99
Notes on the code
  • The loop creates a new array object and stores each value from a into it.
  • b now names a different array object from a, so writing to b does not touch a.
  • The write to b[0] is visible only through b.
OperationArray objects after the lineChange through one name visible through the other?
b = a (reference copy)One shared arrayYes
Loop that creates a new array and copies each valueTwo separate arraysNo, after the copy finishes

Reference copy versus element-by-element copy

Mistakes Beginners Make with Shared Arrays

  • Common mistake

    Assuming that b = a makes an independent copy of the elements

    What it looks like
    a = [10, 20, 30]; b = a; b[0] = 99; then expecting print(a[0]) to show 10
    Why it fails

    The assignment copies the reference, so both names refer to the same array object. There is no second array.

    Do this instead

    Read the assignment as giving a second name to the same object, and write an explicit copy loop when an independent array is needed.

  • Common mistake

    Looking only at the line that prints the wrong value

    What it looks like

    Seeing print(backup[1]) show 5 and searching only the print line for the cause

    Why it fails

    The change happened earlier, in a write through a different name such as scores[1] = 5.

    Do this instead

    Trace upward through the program and find the most recent write to that index of that array object.

  • Common mistake

    Treating a null array variable as an empty array

    What it looks like
    a = None; then reading a[0] and expecting an empty result
    Why it fails

    A null reference refers to no array at all, so there is nothing to index.

    Do this instead

    Check whether a reference is null before reading from it, and keep null failures separate from wrong-value bugs.

  • Common mistake

    Forgetting that a copy loop must run after all the writes that should not be shared

Practice Tracing Shared References

MEDIUM

Trace the following program and state what each print line shows. Name the first line where the value you expected to see differs from the value that appears.

c = [2, 4, 6]
d = c
c[1] = 8
d[2] = 1
print(d[1])
print(c[2])
Hints
  • Ask first whether c = [2, 4, 6] and d = c create one array or two.
  • After line 2, both names refer to the same object, so any write through either name is visible through both.
  • Line 3 changes index 1 and line 4 changes index 2 of the shared array.

Key Takeaways

  • Assigning one array variable to another copies the reference, so both variables refer to the same array object.
  • A write through either variable changes the single shared array, and both variables see the change when they read it.
  • Assignment does not duplicate elements; an independent copy requires creating a new array and copying each value.
  • A null array reference refers to no array, and the same reference-copying rule applies to it.
  • When tracing a wrong value, find which array object each name holds and the most recent statement that wrote the element being read.