I am new to programming and I have this basic problem I cannot fix. I simplified it as much as possible. In this simplified version, I am iterating through an empty list. I just want to store the indices in the "symmetric matrix":
n = 2
B = [[None] * n] * n
print B, "\n"
for i in range(n):
for j in range(n):
B[i][j] = [i, j]
print B
Initially, the list looks like this:
[[None, None], [None, None]]
After looping trough, I would expect the print-out to be:
[[[0, 0], None], [None, None]]
[[[0, 0], [0, 1]], [None, None]]
[[[1, 0], [0, 1]], [[1, 0], None]]
[[[1, 0], [1, 1]], [[1, 0], [1, 1]]]
Instead, I get this:
[[[0, 0], None], [[0, 0], None]]
[[[0, 0], [0, 1]], [[0, 0], [0, 1]]]
[[[1, 0], [0, 1]], [[1, 0], [0, 1]]]
[[[1, 0], [1, 1]], [[1, 0], [1, 1]]]
What am I missing? Thanks for helping out...
What you need instead of the current way you're defining B
is n
"fresh" instances of the sublist:
B = [[None] * n for _ in range(n)]
which is equivalent to but shorter and (for a Pythonista) more readable than:
B = []
for _ in range(n):
B.append([None] * n)
This is because lists in Python are not values but objects; i.e. they are not copied by default. For example:
>>> a = []
>>> b = [a, a] # list of 2 items, both pointing to the same list instance
>>> b[0].append(1) # b[0] refers to the same list instance also referenced by a
>>> print b
[[1], [1]]
whereas:
>>> b = [[], []] # list of 2 distinct sublists
>>> b[0].append(1)
>>> print b
[[1], []]
If you apply that knowledge to
B = [[None] * n] * n
you'll see there's an error in the construction—you're creating a list that contains another list of n
None
values; you're then "upsizing" the list to contain n
of such lists; however, the same list instance will be used just like in the above, more trivial examples.
P.S. more accurately, everything in Python is an object not a value, except in cases where the object is immutable, such as int
s and float
s and str
s etc, it is as if they are values and are always copied—this is because if an object is immutable, you might as well pretend a new reference to it is a new copy of it, because it looks the same and cannot be modified.
Your initialization creates two references to the same list:
n=2
B=[[None]*n]*n
for x in B:
print id(x)
Output:
4534759576
4534759576
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With