2010-05-09 35 views
15

Ai đó có thể giải thích lý do tại sao ví dụ với các số nguyên dẫn đến các giá trị khác nhau cho x và y và ví dụ với kết quả liệt kê trong x và y là cùng một đối tượng?Tham khảo Python

x = 42 
y = x 
x = x + 1 
print x # 43 
print y # 42 

x = [ 1, 2, 3 ] 
y = x 
x[0] = 4 
print x # [4, 2, 3] 
print y # [4, 2, 3] 
x is y # True 
+1

'y = danh sách (x)' * * –

+0

dupe nhiều lần – SilentGhost

+0

wow.! điều này trông giống như những gì tôi đã yêu cầu tháng trước trong http://stackoverflow.com/questions/2573135/2573965#2573965 – wescpy

Trả lời

8

Vì các số nguyên không thay đổi, trong khi danh sách có thể thay đổi. Bạn có thể thấy từ cú pháp. Trong x = x + 1, bạn đang thực sự gán một giá trị mới cho x (chỉ một mình trên LHS). Trong x[0] = 4, bạn đang gọi toán tử chỉ mục trong danh sách và cho nó một tham số - nó thực sự tương đương với x.__setitem__(0, 4), rõ ràng là đang thay đổi đối tượng gốc, chứ không phải tạo đối tượng mới.

+0

Có thể không nhận được các tham chiếu đến các đối tượng không thay đổi được không? – hekevintran

+3

Tất cả "biến" là tham chiếu. Sự khác biệt là bạn không thể thay đổi các vật thể bất biến. Khi chúng được tạo ra, chúng không bao giờ thay đổi - bất kỳ thay đổi nào đã cố gắng sẽ tạo ra một đối tượng mới. –

+2

Chỉ định "chỉ định giá trị mới cho x" là không hợp lý và có khả năng gây nhầm lẫn. Điều đang xảy ra là một tham chiếu đến một đối tượng mới (kết quả của x + 1) được gắn với tên x. Python không có khái niệm về lvalue/rvalue vì mọi thứ đều được tham chiếu - vì vậy sự khác biệt là quan trọng. –

0

Đó là bởi vì khi bạn có danh sách hoặc bộ tảo trong python bạn tạo tham chiếu đến đối tượng. Khi bạn nói rằng y = x bạn tham chiếu đến cùng một đối tượng với y là x. Vì vậy, khi bạn chỉnh sửa đối tượng của x y thay đổi với nó.

+0

Ít bối rối hơn câu trả lời được chấp nhận. –

+2

"khi bạn có một danh sách hoặc một tuple" là khá gây hiểu nhầm. – Ryan

+0

Vâng tôi xin lỗi về điều đó. Điều tôi muốn nói là không quan trọng trong số đó, vì cả hai đều không thay đổi. – Bloeper

4

Nếu bạn làm y = x, y và x là tham chiếu đến cùng một đối tượng. Nhưng số nguyên là không thay đổi và khi bạn làm x + 1, số nguyên mới được tạo ra:

>>> x = 1 
>>> id(x) 
135720760 
>>> x += 1 
>>> id(x) 
135720748 
>>> x -= 1 
>>> id(x) 
135720760 

Khi bạn có một đối tượng có thể thay đổi (ví dụ như danh sách, lớp được định nghĩa bởi chính mình), x được thay đổi bất cứ khi nào y được thay đổi, bởi vì họ chỉ cho một đối tượng duy nhất.

0

Khi câu trả lời trước cho biết mã bạn đã viết gán cùng một đối tượng cho các tên khác nhau như bí danh. Nếu bạn muốn gán một bản sao của danh sách ban đầu vào biến mới (đối tượng trên thực tế) sử dụng giải pháp này:

>>> x=[1,2,3] 
>>> y=x[:] #this makes a new list 
>>> x 
[1, 2, 3] 
>>> y 
[1, 2, 3] 
>>> x[0]=4 
>>> x 
[4, 2, 3] 
>>> y 
[1, 2, 3]