SoFunction
Updated on 2025-03-04

Python's problem of changing actual parameters as formal parameters change

Preface

During the experiment today, it was found that passing the dictionary as a formal parameter of a function into a function and changing the formal parameters within the function will cause the value of the passed dictionary to change accordingly.

This is withc++The difference made me confused, so I wrote this article.

Simple experiment

We conduct experiments on common data types to detect whether the table of formal parameters changes the incoming actual parameters.

variable

def change(a):
    a = 2
    print(a)
b = 1
change(b)
print(b)
>>2
>>1

It can be seen that the value of the variable does not change with the change of formal parameters.

Tuples

def change(a):
    a = a[:2]
    print(a)
b = (1, 2, 3)
change(b)
print(b)
>>(1, 2)
>>(1, 2, 3)

It can be seen that the tuple does not change with the change of formal parameters.

List

def change(a):
    (1)
    print(a)
b = [2, 3]
change(b)
print(b)
>>[2, 3, 1]
>>[2, 3, 1]

It can be seen that the list changes with the change of formal parameters

dictionary

def change(a):
    a[1] = 100
    print(a)
b = {1: 1, 2: 2}
change(b)
print(b)
>>{1: 100, 2: 2}
>>{1: 100, 2: 2}

It can be seen that the dictionary changes with the change of formal parameters.

reason

We've metvariableandImmutableDifferences between data types. existPythonIn this case, the data type can be variable or immutable.

The data types we usually use (integral, floating point, string, boolean, and tuple) are all immutable, butLists and dictionaries are mutable.

This meansGlobal lists or dictionaries can be changed even when used inside a function, we can also see this problem through the above examples.

Examples of immutable data

a = 1

variableaThe function is similar to a pointer to 1.

The data type of a variable is immutable, and once a variable is created, it cannot be changed.

If we executea = a + 1

Instead of updating 1 to 2, we actually point the pointer from 1 to 2.

Variable data distance

list1 = [1, 2, 3]

If we add a value at the end of the list, we do notlist1Point to another list, but update the existing list directly.

If we create multiple list variables, as long as they point to the same list, then when the list changes, these list variables will change.

list1 = [1, 2, 3]
list2 = list1
(4)
print(list1)
print(list2)
>>[1, 2, 3, 4]
>>[1, 2, 3, 4]

Experience

From these two examples, we can intuitively feel the difference between mutable data types and immutable data types.

Our operations on variable data are operated directly on itself.

Operations on immutable data are to point the pointer to another location, rather than changing itself.

Keep variable data unchanged

When we write code, we often write various functions. We do not want the actual parameters passed into the function to be changed inside the function. So what should I do?

It's actually very simple, use.copy()Methods just copy the list or dictionary.

list1 = [1, 2, 3]
list2 = ()
(4)
print(list1)
print(list2)
>>[1, 2, 3, 4]
>>[1, 2, 3]

.copy()The method creates a new copy, solist2Will not point tolist1Point to the list, but to a new list.

In this case,list1andlist2They are independent of each other and do not affect each other.

def change(a):
    temp = ()
    (4)
    print(temp)
list1 = [1, 2, 3]
change(list1)
print(list1)
>>[1, 2, 3, 4]
>>[1, 2, 3]

It can be seen that in this way we solve the problem of change in actual parameters caused by changes in formal parameters. The same is true for dictionaries.

Replenish

Deep and shallow copy

>>> import copy
>>> origin = [1, 2, [3, 4]]
#origin has three elements: 1, 2, [3, 4]>>> cop1 = (origin)
>>> cop2 = (origin)
>>> cop1 == cop2  # Determine whether the values ​​of cop1 and cop2 are the sameTrue
>>> cop1 is cop2  # Determine whether cop1 and cop2 are the same objectFalse 
#cop1 and cop2 look the same, but are no longer the same object>>> origin[2][0] = "hey!" 
>>> origin
[1, 2, ['hey!', 4]]
>>> cop1
[1, 2, ['hey!', 4]]
>>> cop2
[1, 2, [3, 4]]

Copy does not completely copy child objects of a complex object. What are subobjects of complex objects?

For example, nested lists (multi-dimensional lists) in lists and nested dictionaries (multi-dimensional dictionaries) in dictionaries are all sub-objects of complex objects.

For sub-objects,pythonIt will be stored as a public image, and all copies of it will be referenced (that is, pointing to the same area with a pointer). Therefore, when the value of one of the references changes, the values ​​of the other references also change.

Copy complex objects, we also want to copy them all (including sub-objects), and then we can use them.deepcopy()Deep copying of functions

import copy
a = [1, 2, [3, 4]]
b = (a)  # Deep copy

Summarize

The above is personal experience. I hope you can give you a reference and I hope you can support me more.