← Python lessons

Python Names and References: Aliasing, is and copy()

Part of a free Python course — sign up to save your progress and get AI hints.Sign up free

A Python variable is a reference: a name that points at a value. Two names can point at the same list, so a change through one name shows through the other.

Read Variables and Lists first.

This lesson explains one thing: when two names share a list, and how to give each name its own list. Every block below runs on its own and prints the result shown under it.

Two names, one list

b = a does not copy the list. It gives the same list a second name, an alias.

a = [1, 2]
b = a
b.append(3)
print(a)
print(b)

Both print [1, 2, 3]. There is only one list.

Changing the list vs storing a new value

append() changes the list itself. = makes the name point at a new value and leaves the old one alone.

a = [1, 2]
b = a
b = [9]
print(a)
print(b)

This prints [1, 2] then [9]. After b = [9], the two names point at different lists.

Numbers and strings cannot be changed in place. n += 1 always stores a new number, so aliasing never surprises you with them.

Check with is and ==

== asks "same value?". is asks "same object?".

a = [1, 2]
b = a
c = [1, 2]
print(a == c)
print(a is c)
print(a is b)

This prints True, False, True. c holds an equal list, but not the same one. Use == to compare values. Use is mainly for None, as in if result is None:.

Make a real copy with copy()

copy() builds a new list with the same items, so the two names stay separate.

a = [1, 2]
b = a.copy()
b.append(3)
print(a)
print(b)

This prints [1, 2] then [1, 2, 3]. a[:] and list(a) make the same kind of copy.

Note: copy() is a shallow copy. If the list holds other lists, the copy shares those inner lists. Use copy.deepcopy() from the copy module when inner lists must be separate too.

Function arguments are aliases too

A function parameter is another name for the list you pass in.

def add_bonus(scores):
    scores.append(10)

mine = [5, 7]
add_bonus(mine)
print(mine)

This prints [5, 7, 10]. Pass mine.copy() if the function must not change your list.

See also: Lists, Augmented assignment.

Your turn

Make backup a real copy of team and alias a second name for team. Append "Lee" to team, then print all three lists and two checks: is alias the same object as team, and is backup?

team = ["Ada", "Sam"]
# add: backup as a copy of team, alias as another name for team,
# then append "Lee" to team and print team, alias, backup,
# alias is team, and backup is team

Expected output

['Ada', 'Sam', 'Lee']
['Ada', 'Sam', 'Lee']
['Ada', 'Sam']
True
False