Python Assignment and Reference

PythonPythonBeginner
Practice Now

Introduction

In this lab, we'll cover the basics of Python assignment and reference. We'll explore how Python handles assignments, how to create references, and how to work with mutable and immutable objects.

Introduction to Python Assignments

In Python, assignment is the process of binding a name to an object. Assignment statements have the following general form:

variable = expression

The expression on the right-hand side is evaluated, and its value is assigned to the variable on the left-hand side.

Let's look at a simple example:

Simple Test

Open the Terminal and typing the following command in the terminal.

python3

Then, enter the following code.

## Assign the value 42 to the variable 'x' and print it.
x = 42
print(x)

Output:

42

Here, we assign the x to the variable 42 using the operator =. Then, we print the values of x.

Understanding References

In Python, variables are references to objects. When you assign a value to a variable, you're actually creating a reference to the object that represents the value.

Here's an example to illustrate this concept:

## Illustrate Python references.
x = [1, 2, 3]
y = x
y.append(4)

print("x:", x)
print("y:", y)

Output:

x: [1, 2, 3, 4]
y: [1, 2, 3, 4]

In this example, both x and y refer to the same list object. When we modify the list through the y reference by appending 4, the change is reflected in both x and y.

Mutable and Immutable Objects

Python has two types of objects: mutable and immutable.

Mutable objects can be modified after they are created. Lists, dictionaries, and sets are examples of mutable objects.

Immutable objects cannot be modified once they are created. Integers, floats, strings, and tuples are examples of immutable objects.

Let's look at an example that demonstrates the difference between mutable and immutable objects:

## Mutable object example
mutable_list = [1, 2, 3]
another_mutable_list = mutable_list
another_mutable_list.append(4)
print("mutable_list:", mutable_list)

Output:

mutable_list: [1, 2, 3, 4]

mutable_list append a 4 to the end of the list because it's mutable objects, but immutable objects cannot be modified once they are created.

## Immutable object example
immutable_string = "hello"
another_immutable_string = immutable_string
another_immutable_string = another_immutable_string.upper()
print("immutable_string:", immutable_string)

Output:

immutable_string: hello

It doesn't have any change, and if we want to change the immutable_string as follows, Python shell will throws a TypeError:

immutable_string[0] = '1'

Output:

TypeError: 'str' object does not support item assignment

Examples

Let's see a few more examples to reinforce the concepts we've learned:

Example 1: Function with mutable default argument

Avoid using mutable objects as default arguments in functions:

def bad_append(new_item, a_list=[]):
    a_list.append(new_item)
    return a_list

print(bad_append('one'))

Output:

['one']

It looks good, but if we call this function again:

print(bad_append('two'))

Output:

['one', 'two']

The problem here, is that the default value of a_list is evaluated at function definition time. So every time you call the function, you get the same default value.The correct way is to create it at run time instead, inside the function.

def append_to_list(item: int, a_list: list = None) -> list:
    """Append an item to a list and return the updated list."""
    if a_list is None:
        a_list = []
    a_list.append(item)
    return a_list

list_a = append_to_list(1, [1, 2, 3])
print(list_a)

Output:

[1, 2, 3, 1]

Example 2: Copying mutable objects

Use the copy module to create a new object when you want to work with a copy of a mutable object:

import copy

## Demonstrate the use of the copy module.
original_list = [1, 2, 3]
copied_list = copy.copy(original_list)
copied_list.append(4)

print("original_list:", original_list)
print("copied_list:", copied_list)

Output:

original_list: [1, 2, 3]
copied_list: [1, 2, 3, 4]

In this example, copied_list is a new object that is a copy of original_list. When we append 4 to copied_list, original_list remains unchanged.

Example 3: Deep copying mutable objects

For nested mutable objects, using the copy function doesn't work:

## your copy example here
original_nested_list = [[1, 2], [3, 4]]
copied_nested_list = copy.copy(original_nested_list)
copied_nested_list[0].append(5)

print("original_nested_list:", original_nested_list)
print("copied_nested_list:", copied_nested_list)

Output:

original_nested_list: [[1, 2, 5], [3, 4]]
copied_nested_list: [[1, 2, 5], [3, 4]]

We can see that when we append 5 to copied_nested_list, the original_nested_list also appends 5. So you should use the deepcopy function instead.:

## your deepcopy example here
original_nested_list = [[1, 2], [3, 4]]
deep_copied_list = copy.deepcopy(original_nested_list)
deep_copied_list[0].append(5)

print("original_nested_list:", original_nested_list)
print("deep_copied_list:", deep_copied_list)

Output:

original_nested_list: [[1, 2], [3, 4]]
deep_copied_list: [[1, 2, 5], [3, 4]]

In this example, deepcopy function copies the original_nested_list recursively, while the copy function creates a reference object to the first-level data of the original_nested_list.

Summary

In this Python programming tutorial, we covered the basics of Python assignment and reference. We explored how Python handles assignments, how to create references, and how to work with mutable and immutable objects. By understanding these concepts, you'll be better equipped to write efficient and correct Python code.

Other Python Tutorials you may like