Copying Arrays Element by Element
Assigning one array variable to another copies the reference, so both variables refer to the same array object.
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?
Reveal 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.
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
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.
99- 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.
a = [10, 20, 30]
b = aTwo names, one array: a and b both name the array holding 10, 20, 30.
a = [10, 20, 30]
b = a
b[0] = 99The same single array now holds 99, 20, 30. Reading a[0] or b[0] gives 99.
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.
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])- 1Line 1
scores names a new array holding 4, 7, 9. Nothing else exists yet.
- 2Line 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.
- 3Line 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.
- 4Line 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.
- 5Line 5
print(backup[1])reads index 1 through backup. The shared array holds 5 there, so 5 is printed. - 6Line 6
print(scores[2])reads index 2 through scores. The write from line 3 is visible, so 0 is printed.
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.
- 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.
10
99- 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.
| Operation | Array objects after the line | Change through one name visible through the other? |
|---|---|---|
| b = a (reference copy) | One shared array | Yes |
| Loop that creates a new array and copies each value | Two separate arrays | No, 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 likea = [10, 20, 30]; b = a; b[0] = 99; then expecting print(a[0]) to show 10Why it failsThe assignment copies the reference, so both names refer to the same array object. There is no second array.
Do this insteadRead 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 likeSeeing print(backup[1]) show 5 and searching only the print line for the cause
Why it failsThe change happened earlier, in a write through a different name such as scores[1] = 5.
Do this insteadTrace 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 likea = None; then reading a[0] and expecting an empty resultWhy it failsA null reference refers to no array at all, so there is nothing to index.
Do this insteadCheck 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
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.