Việc sửa đổi danh sách trong python có nghĩa là gì?

Trong ví dụ đơn giản sau đây, các biến x và y được gán và chuyển vào một hàm, trong đó, dưới các tên mới, chúng được sửa đổi, tính tổng và trả về kết quả

x,y = 2,3
def some_function(a,b):
    z = a*2 + b*2
    return z

z = some_function(x,y)
print(x, y, z)

> 2 3 10 

Đương nhiên, x và y không thay đổi, nhưng đó là điều xảy ra nếu chúng là danh sách

x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")

z = [[2, -2], [3, -3]] # hoàn toàn chính xác
x (now) = [[2, -2]] # danh sách ban đầu . ?)
y (bây giờ) = [[3, -3]]

Vì vậy, việc chuyển các danh sách tới một hàm nơi chúng được sử dụng với các tên biến khác nhau khiến chúng bị thay đổi? . Tôi nghĩ các hàm Python được cho là tạo các biến chỉ cục bộ mới

Ghi chú. Các danh sách ban đầu không và không thể bất biến. Sau này tôi sẽ sửa đổi chúng, nhưng tôi sẽ cần bản gốc để làm điều đó

Ai đó có thể giải thích chuyện gì đang xảy ra ở đây không và làm cách nào tôi có thể ngăn danh sách của mình bị thay đổi khi được chuyển đến một chức năng?

Tôi đang cố gắng thực hiện sửa đổi tại chỗ danh sách danh sách ở cấp danh sách chính. Tuy nhiên, khi tôi cố gắng sửa đổi biến lặp (

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
5 trong ví dụ bên dưới), nó dường như tạo ra một con trỏ mới tới nó thay vì sửa đổi nó


Ví dụ nhỏ nhất về vấn đề của tôi

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]

Ví dụ trên là một ví dụ tầm thường về vấn đề của tôi. Có cách nào để sửa đổi

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6 theo từng phần tử, tại chỗ và để các thay đổi xuất hiện trong C không?


Ví dụ ít tầm thường hơn về vấn đề của tôi. Tôi đang chuyển tất cả 0 thành 1 và ngược lại

A =  [[1,1,0],
      [1,0,1],
      [0,0,0]]
for row in A:
    row = list(map(lambda val: 1 - val, row))
print(A)

Kỳ vọng

A = [[0,0,1],
     [0,1,0],
     [1,1,1]]

Trả lại

A = [[1,1,0],
     [1,0,1],
     [0,0,0]]

cập nhật. Câu trả lời tuyệt vời cho đến nay. Tôi quan tâm đến cách biến lặp lại (

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
5 trong ví dụ thứ hai) được liên kết với biến lặp lại (
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
8 trong ví dụ thứ hai)

Nếu tôi làm như sau, đảo ngược từng danh sách con của A, thì nó hoạt động hoàn hảo

Tại sao ví dụ sau, nơi tôi sửa đổi biến lặp lại hoạt động nhưng các ví dụ trên thì không?

Các hàm của Python (cả hàm tích hợp và hàm tùy chỉnh do chúng tôi tự viết) là những công cụ quan trọng để làm việc với dữ liệu. Nhưng những gì họ làm với dữ liệu của chúng tôi có thể hơi khó hiểu và nếu chúng tôi không biết điều gì đang xảy ra, điều đó có thể gây ra lỗi nghiêm trọng trong quá trình phân tích của chúng tôi

Trong hướng dẫn này, chúng ta sẽ xem xét kỹ cách Python xử lý các loại dữ liệu khác nhau khi chúng được thao tác bên trong các hàm và tìm hiểu cách đảm bảo rằng dữ liệu của chúng ta chỉ được thay đổi khi chúng ta muốn nó được thay đổi.

Cách ly bộ nhớ trong chức năng

Để hiểu cách Python xử lý các biến toàn cục bên trong các hàm, hãy làm một thử nghiệm nhỏ. Chúng ta sẽ tạo hai biến toàn cục, number_1 và number_2, và gán chúng cho các số nguyên 5 và 10. Sau đó, chúng ta sẽ sử dụng các biến toàn cục đó làm đối số trong một hàm thực hiện một số phép toán đơn giản. Chúng tôi cũng sẽ sử dụng tên biến làm tên tham số của hàm. Sau đó, chúng ta sẽ xem liệu tất cả việc sử dụng biến bên trong hàm của chúng ta có ảnh hưởng đến giá trị toàn cầu của các biến này hay không

number_1 = 5
number_2 = 10

def multiply_and_add(number_1, number_2):
    number_1 = number_1 * 10
    number_2 = number_2 * 10
    return number_1 + number_2

a_sum = multiply_and_add(number_1, number_2)
print(a_sum)
print(number_1)
print(number_2)
150
5
10

Như chúng ta có thể thấy ở trên, hàm hoạt động chính xác và giá trị của các biến toàn cục

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
0 và
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
1 không thay đổi, mặc dù chúng ta đã sử dụng chúng làm đối số và tên tham số trong hàm của mình. Điều này là do Python lưu trữ các biến từ một hàm ở một vị trí bộ nhớ khác với các biến toàn cục. Họ bị cô lập. Do đó, biến
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
0 có thể có một giá trị (5) trên toàn cục và một giá trị khác (50) bên trong hàm, nơi nó được tách biệt

(Nhân tiện, nếu bạn bối rối về sự khác biệt giữa tham số và đối số, tài liệu của Python về chủ đề này khá hữu ích. )

Điều gì về danh sách và từ điển?

danh sách

Chúng ta đã thấy rằng những gì chúng ta làm với một biến như

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
0 ở trên bên trong một hàm không ảnh hưởng đến giá trị toàn cầu của nó. Nhưng
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
0 là một số nguyên, là một kiểu dữ liệu khá cơ bản. Điều gì xảy ra nếu chúng ta thử cùng một thử nghiệm với một loại dữ liệu khác, chẳng hạn như danh sách?

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
5

Như chúng ta có thể thấy, ở đây giá trị toàn cục của

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6 đã được cập nhật, mặc dù giá trị của nó chỉ được thay đổi bên trong hàm

từ điển

Bây giờ, hãy viết một hàm lấy từ điển làm đối số để xem liệu biến từ điển toàn cục có bị sửa đổi khi nó cũng được thao tác bên trong hàm không

Để làm cho điều này thực tế hơn một chút, chúng tôi sẽ sử dụng dữ liệu từ bộ dữ liệu

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
7 được sử dụng trong khóa học Nguyên tắc cơ bản về Python của chúng tôi (dữ liệu có sẵn để tải xuống tại đây)

Trong đoạn mã bên dưới, chúng tôi đang bắt đầu với một từ điển chứa số lượng ứng dụng với từng xếp hạng độ tuổi trong tập dữ liệu (do đó, có 4.433 ứng dụng được xếp hạng “4+”, 987 ứng dụng được xếp hạng “9+”, v.v. ). Hãy tưởng tượng rằng chúng ta muốn tính tỷ lệ phần trăm cho từng xếp hạng độ tuổi, vì vậy chúng ta có thể biết được xếp hạng độ tuổi nào phổ biến nhất trong số các ứng dụng trong App Store

Để làm điều này, chúng ta sẽ viết một hàm có tên là

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
8 sẽ lấy một từ điển làm đối số và chuyển đổi số đếm thành tỷ lệ phần trăm. Chúng tôi sẽ cần bắt đầu đếm từ 0 và sau đó lặp lại từng giá trị trong từ điển, thêm chúng vào số đếm để chúng tôi nhận được tổng số xếp hạng. Sau đó, chúng tôi sẽ lặp lại từ điển một lần nữa và thực hiện một số phép toán cho từng giá trị để tính tỷ lệ phần trăm

x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
9

Trước khi xem kết quả, hãy nhanh chóng xem lại những gì đang xảy ra ở trên. Sau khi gán từ điển xếp hạng độ tuổi của ứng dụng cho biến

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
9, chúng tôi tạo một hàm mới có tên là
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
8 nhận một đối số duy nhất.
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
51

Để biết tỷ lệ phần trăm ứng dụng rơi vào từng xếp hạng độ tuổi, chúng tôi cần biết tổng số ứng dụng, vì vậy, trước tiên, chúng tôi đặt một biến mới có tên là

x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
52 đến
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
53, sau đó lặp qua từng khóa trong
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
51, thêm nó vào
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
52

Sau khi hoàn tất, tất cả những gì chúng ta cần làm là lặp lại

x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
51, chia từng mục cho tổng và sau đó nhân kết quả với 100. Điều này sẽ cung cấp cho chúng tôi một từ điển với tỷ lệ phần trăm

Nhưng điều gì sẽ xảy ra khi chúng ta sử dụng toàn cầu

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
9 làm đối số cho chức năng mới này?

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
9
A =  [[1,1,0],
      [1,0,1],
      [0,0,0]]
for row in A:
    row = list(map(lambda val: 1 - val, row))
print(A)
0

Giống như chúng ta đã thấy với các danh sách, biến toàn cục

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
9 của chúng ta đã được thay đổi, mặc dù nó chỉ được sửa đổi bên trong hàm
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
8 mà chúng ta đã tạo

Vì vậy, những gì đang thực sự xảy ra ở đây?

Các kiểu dữ liệu có thể thay đổi và không thể thay đổi

Trong Python, kiểu dữ liệu có thể là mutable (có thể thay đổi) hoặc immutable (không thể thay đổi). Và trong khi hầu hết các kiểu dữ liệu mà chúng ta đã làm việc trong phần giới thiệu Python là bất biến (bao gồm số nguyên, số float, chuỗi, Boolean và bộ dữ liệu), danh sách và từ điển có thể thay đổi. Điều đó có nghĩa là một danh sách toàn cầu hoặc từ điển có thể được thay đổi ngay cả khi nó được sử dụng bên trong một hàm, giống như chúng ta đã thấy trong các ví dụ ở trên

Để hiểu sự khác biệt giữa có thể thay đổi (có thể thay đổi) và không thể thay đổi (không thể thay đổi), thật hữu ích khi xem cách Python thực sự xử lý các biến này

Hãy bắt đầu bằng cách xem xét một phép gán biến đơn giản

A =  [[1,1,0],
      [1,0,1],
      [0,0,0]]
for row in A:
    row = list(map(lambda val: 1 - val, row))
print(A)
3

Tên biến

x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
90 đóng vai trò như một con trỏ hướng tới
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
91 và nó giúp chúng ta truy xuất
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
91 bất cứ khi nào chúng ta muốn

Việc sửa đổi danh sách trong python có nghĩa là gì?

x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
91 là số nguyên và số nguyên là kiểu dữ liệu không thay đổi. Nếu một loại dữ liệu là bất biến, điều đó có nghĩa là nó không thể được cập nhật sau khi được tạo. Nếu chúng tôi làm
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
94, chúng tôi không thực sự cập nhật
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
91 thành
x = [[2,2]]
y = [[3,3]]  

def some_function(a,b):
    z = a + b                         # concatenate lists

    for i in range(len(z)):           # switch sign of 2nd elements
        z[i][1] *= -1
    return z

z = some_function(x,y)

print(f"z = {z}") 
print(f"x (now) = {x}")
print(f"y (now) = {y}")
96. Trong hình ảnh động dưới đây, chúng ta có thể thấy rằng

  • x = [[2,2]]
    y = [[3,3]]  
    
    def some_function(a,b):
        z = a + b                         # concatenate lists
    
        for i in range(len(z)):           # switch sign of 2nd elements
            z[i][1] *= -1
        return z
    
    z = some_function(x,y)
    
    print(f"z = {z}") 
    print(f"x (now) = {x}")
    print(f"y (now) = {y}")
    
    90 ban đầu chỉ về phía
    x = [[2,2]]
    y = [[3,3]]  
    
    def some_function(a,b):
        z = a + b                         # concatenate lists
    
        for i in range(len(z)):           # switch sign of 2nd elements
            z[i][1] *= -1
        return z
    
    z = some_function(x,y)
    
    print(f"z = {z}") 
    print(f"x (now) = {x}")
    print(f"y (now) = {y}")
    
    91
  • x = [[2,2]]
    y = [[3,3]]  
    
    def some_function(a,b):
        z = a + b                         # concatenate lists
    
        for i in range(len(z)):           # switch sign of 2nd elements
            z[i][1] *= -1
        return z
    
    z = some_function(x,y)
    
    print(f"z = {z}") 
    print(f"x (now) = {x}")
    print(f"y (now) = {y}")
    
    94 được chạy và điều này di chuyển con trỏ từ
    x = [[2,2]]
    y = [[3,3]]  
    
    def some_function(a,b):
        z = a + b                         # concatenate lists
    
        for i in range(len(z)):           # switch sign of 2nd elements
            z[i][1] *= -1
        return z
    
    z = some_function(x,y)
    
    print(f"z = {z}") 
    print(f"x (now) = {x}")
    print(f"y (now) = {y}")
    
    91 đến
    x = [[2,2]]
    y = [[3,3]]  
    
    def some_function(a,b):
        z = a + b                         # concatenate lists
    
        for i in range(len(z)):           # switch sign of 2nd elements
            z[i][1] *= -1
        return z
    
    z = some_function(x,y)
    
    print(f"z = {z}") 
    print(f"x (now) = {x}")
    print(f"y (now) = {y}")
    
    96, nó không thực sự thay đổi số
    x = [[2,2]]
    y = [[3,3]]  
    
    def some_function(a,b):
        z = a + b                         # concatenate lists
    
        for i in range(len(z)):           # switch sign of 2nd elements
            z[i][1] *= -1
        return z
    
    z = some_function(x,y)
    
    print(f"z = {z}") 
    print(f"x (now) = {x}")
    print(f"y (now) = {y}")
    
    91

Việc sửa đổi danh sách trong python có nghĩa là gì?
Việc sửa đổi danh sách trong python có nghĩa là gì?

Các loại dữ liệu có thể thay đổi như danh sách và từ điển hoạt động khác nhau. Chúng có thể được cập nhật. Vì vậy, ví dụ, hãy tạo một danh sách rất đơn giản

A = [[0,0,1],
     [0,1,0],
     [1,1,1]]
7

Nếu chúng tôi thêm một

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
93 vào cuối danh sách này, chúng tôi không chỉ trỏ
c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
94 vào một danh sách khác, chúng tôi đang trực tiếp cập nhật danh sách hiện có

Việc sửa đổi danh sách trong python có nghĩa là gì?
Việc sửa đổi danh sách trong python có nghĩa là gì?

Ngay cả khi chúng ta tạo nhiều biến danh sách, miễn là chúng trỏ đến cùng một danh sách, tất cả chúng sẽ được cập nhật khi danh sách đó thay đổi, như chúng ta có thể thấy trong đoạn mã bên dưới

A = [[1,1,0],
     [1,0,1],
     [0,0,0]]
0
150
5
10
0

Đây là hình ảnh động về những gì đang thực sự xảy ra trong đoạn mã trên

Việc sửa đổi danh sách trong python có nghĩa là gì?
Việc sửa đổi danh sách trong python có nghĩa là gì?

Điều này giải thích tại sao các biến toàn cầu của chúng tôi đã bị thay đổi khi chúng tôi thử nghiệm với các danh sách và từ điển trước đó. Vì danh sách và từ điển có thể thay đổi nên việc thay đổi chúng (thậm chí bên trong một hàm) sẽ thay đổi chính danh sách hoặc từ điển, đây không phải là trường hợp đối với các kiểu dữ liệu không thể thay đổi

Giữ các kiểu dữ liệu có thể thay đổi không thay đổi

Nói chung, chúng ta không muốn các hàm của mình thay đổi các biến toàn cục, ngay cả khi chúng chứa các kiểu dữ liệu có thể thay đổi như danh sách hoặc từ điển. Đó là bởi vì trong các phân tích và chương trình phức tạp hơn, chúng ta có thể thường xuyên sử dụng nhiều chức năng khác nhau. Nếu tất cả họ đang thay đổi danh sách và từ điển mà họ đang làm việc, thì việc theo dõi những gì đang thay đổi những gì có thể trở nên khá khó khăn.

Rất may, có một cách dễ dàng để giải quyết vấn đề này. chúng ta có thể tạo một bản sao của danh sách hoặc từ điển bằng phương thức Python tích hợp có tên là

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95

Nếu bạn chưa tìm hiểu về các phương pháp, đừng lo lắng. Chúng được đề cập trong khóa học Python trung cấp của chúng tôi, nhưng đối với hướng dẫn này, tất cả những gì bạn cần biết là

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95 hoạt động giống như
c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
97

150
5
10
1

Hãy xem lại hàm mà chúng ta đã viết cho danh sách và cập nhật nó để những gì xảy ra bên trong hàm của chúng ta không thay đổi

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6. Tất cả những gì chúng ta cần làm là thay đổi đối số mà chúng ta truyền vào hàm của mình từ
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6 thành
A =  [[1,1,0],
      [1,0,1],
      [0,0,0]]
for row in A:
    row = list(map(lambda val: 1 - val, row))
print(A)
00

150
5
10
2____73

Như chúng ta có thể thấy, điều này đã khắc phục vấn đề của chúng ta. Đây là lý do tại sao. sử dụng

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95 tạo một bản sao riêng của danh sách, để thay vì trỏ đến chính
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6,
A =  [[1,1,0],
      [1,0,1],
      [0,0,0]]
for row in A:
    row = list(map(lambda val: 1 - val, row))
print(A)
03 trỏ đến một danh sách mới bắt đầu bằng một bản sao của
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6. Bất kỳ thay đổi nào được thực hiện đối với
A =  [[1,1,0],
      [1,0,1],
      [0,0,0]]
for row in A:
    row = list(map(lambda val: 1 - val, row))
print(A)
03 sau thời điểm đó đều được thực hiện cho danh sách riêng biệt đó, không phải chính
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6, do đó, giá trị toàn cầu của
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6 không thay đổi

Việc sửa đổi danh sách trong python có nghĩa là gì?

Tuy nhiên, giải pháp này vẫn chưa hoàn hảo vì chúng ta sẽ phải nhớ thêm

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95 mỗi khi truyền một đối số cho hàm của mình, nếu không sẽ có nguy cơ vô tình thay đổi giá trị chung của
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6. Nếu chúng tôi không muốn phải lo lắng về điều đó, chúng tôi thực sự có thể tạo bản sao danh sách đó bên trong chính chức năng đó

150
5
10
4
150
5
10
3

Với cách tiếp cận này, chúng ta có thể chuyển một biến toàn cục có thể thay đổi một cách an toàn như

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
6 vào hàm của mình và giá trị toàn cục sẽ không bị thay đổi vì chính hàm đó tạo một bản sao và sau đó thực hiện các thao tác của nó trên bản sao đó

Phương pháp

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95 cũng hoạt động với từ điển. Như với danh sách, chúng ta có thể chỉ cần thêm
c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95 vào đối số mà chúng ta chuyển hàm của mình để tạo một bản sao sẽ được sử dụng cho hàm mà không thay đổi biến ban đầu

150
5
10
6
150
5
10
7

Nhưng một lần nữa, sử dụng phương pháp đó có nghĩa là chúng ta cần nhớ thêm

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95 mỗi khi chúng ta chuyển một từ điển vào hàm
initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
8 của mình. Nếu chúng tôi sẽ sử dụng chức năng này thường xuyên, có thể tốt hơn là triển khai sao chép vào chính chức năng đó để chúng tôi không phải nhớ thực hiện việc này

Bên dưới, chúng ta sẽ sử dụng

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95 bên trong hàm. Điều này sẽ đảm bảo rằng chúng ta có thể sử dụng nó mà không cần thay đổi các biến toàn cục mà chúng ta chuyển cho nó dưới dạng đối số và chúng ta không cần phải nhớ thêm
c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95 vào mỗi đối số mà chúng ta chuyển

150
5
10
8
150
5
10
7

Như chúng ta có thể thấy, việc sửa đổi chức năng của chúng ta để tạo một bản sao của từ điển và sau đó chỉ thay đổi số đếm thành tỷ lệ phần trăm trong bản sao đó đã cho phép chúng ta thực hiện thao tác chúng ta muốn mà không thực sự thay đổi

initial_list = [1, 2, 3]

def duplicate_last(a_list):
    last_element = a_list[-1]
    a_list.append(last_element)
    return a_list

new_list = duplicate_last(a_list = initial_list)
print(new_list)
print(initial_list)
9

kết luận

Trong hướng dẫn này, chúng ta đã xem xét sự khác biệt giữa các loại dữ liệu có thể thay đổi, có thể thay đổi và các loại dữ liệu không thay đổi, không thể thay đổi. Chúng tôi đã học cách sử dụng phương pháp

c = [1,2,3]
for x in c:
    x = x + 3
print(c) #returns [1,2,3], expected [4,5,6]
95 để tạo bản sao của các loại dữ liệu có thể thay đổi như danh sách và từ điển để chúng tôi có thể làm việc với chúng trong các hàm mà không thay đổi giá trị chung của chúng

Hướng dẫn này có hữu ích không?

Chọn con đường của bạn để tiếp tục học các kỹ năng dữ liệu có giá trị

Việc sửa đổi danh sách trong python có nghĩa là gì?

Việc sửa đổi danh sách trong python có nghĩa là gì?

Hướng dẫn Python

Thực hành các kỹ năng lập trình Python của bạn khi bạn làm việc với các hướng dẫn miễn phí của chúng tôi

Các khóa học khoa học dữ liệu

Cam kết học tập với các khóa học khoa học dữ liệu tương tác, trong trình duyệt của bạn bằng Python, R, SQL, v.v.

người mới bắt đầu từ điểnchức năngkiểu dữ liệu có thể thay đổidanh sáchkiểu dữ liệu có thể thay đổipythonHướng dẫn

Việc sửa đổi danh sách trong python có nghĩa là gì?

Thông tin về các Tác giả

Charlie Custer

Charlie là sinh viên ngành khoa học dữ liệu và cũng là nhà tiếp thị nội dung tại Dataquest. Trong thời gian rảnh rỗi, anh ấy học đi xe đạp leo núi và làm video về nó

Điều gì đang sửa đổi một danh sách trong Python?

Danh sách trong python là các loại có thể thay đổi, có nghĩa là nó có thể thay đổi sau khi gán một số giá trị. Danh sách tương tự như mảng trong các ngôn ngữ lập trình khác. .
Thay đổi phần tử đầu tiên mylist[0]=value
Thay đổi phần tử thứ ba mylist[2]=value
Thay đổi phần tử thứ tư mylist[3]=value

Danh sách có thể được sửa đổi Python không?

Và trong khi hầu hết các kiểu dữ liệu mà chúng ta đã làm việc trong phần giới thiệu Python là bất biến (bao gồm số nguyên, số float, chuỗi, Boolean và bộ), danh sách và từ điển có thể thay đổi . Điều đó có nghĩa là một danh sách toàn cầu hoặc từ điển có thể được thay đổi ngay cả khi nó được sử dụng bên trong một hàm, giống như chúng ta đã thấy trong các ví dụ ở trên. . That means a global list or dictionary can be changed even when it's used inside of a function, just like we saw in the examples above.