Let me make a list and change one element like this:
list = [float("inf")] * 3
list[2] = 0
then I print it, It prints
print(list)
> [inf, inf, 0]
I thought each element references the same one, but it's not.
However, when I make a second-dimension list and change one element like this:
list = [[float("inf")] * 3] * 3
list[2][2] = 0
then I print it, it prints
print(list)
> [[inf, inf, 0], [inf, inf, 0], [inf, inf, 0]]
then I am in chaos. in the first dimension, changing one element reflects to one element. but in second dimension, all rows reflect the change. how can it be happen?
I thought the second result should be:
print(list)
> [[inf, inf, inf], [inf, inf, inf], [inf, inf, 0]]
and according to the second result, shouldn't the first result be like this?
print(list)
> [0, 0, 0]
please, help me. I can't understand it.
You're misunderstanding what happens in the first example:
nums = [float("inf")] * 3
nums[2] = 0
print(nums)
# [inf, inf, 0]
After the first line is executed, all of the list elements do reference the same object. You can see this by printing all their id
s and seeing that they're the same:
>>> nums = [float("inf")] * 3
>>> for n in nums:
... print(id(n))
...
2996959434960
2996959434960
2996959434960
The part you misinterpreted is what happens when you do nums[2] = 0
. This does not mutate one of the inf
s (because they are in fact all the same object, which is itself immutable). Assigning something to an object's name never modifies the object itself, only the name.
So subscript assignment mutates the list so that it's 2-th index (i.e. one of the 3 "names" for that one inf
object) now references a different object:
>>> nums[2] = 0
>>> for n in nums:
... print(id(n))
...
2996959434960
2996959434960
2996958396624
When you have a list of references to the same list, and you mutate the inner list, the top-level list is unchanged, so it sees the inner list change across all three of its "names".
It may help to think of:
nums = [float("inf")] * 3
as being equivalent to:
n = float("inf")
num0, num1, num2 = n, n, n
All three num
variables point to the same n
. When you reassign one of them:
num2 = 0
you reassign that variable, but you're not changing n
or any of the other num
s.
The same exact logic applies if you do:
nums = [float("inf")] * 3
arr0, arr1, arr2 = nums, nums, nums