On 2014-12-31 16:18, Steven D'Aprano wrote:

py> grid[1][1] = 99  # Adjust a single cell.
py> print(grid)
[[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0]]

while you expected:

[[0, 0, 0, 0, 0], [0, 99, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]


Am I right?

Yes, although perhaps not so much 'expected' as 'hoped.'



The problem is that you guessed that list multiplication *copies* the
items. It does not. It just repeats them. So:

I don't think I understand the distinction between 'copies' and 'repeats'. I think I understand the difference between copy and deep copy and I think that is the issue here but it isn't yet clear.

I hope I'm not trying your patience too much:
Do I have the correct explanations for these
behaviours?  (python3 on ubuntu14.04)

s_grid = [[0]*5 for i in range(4)]
# So for each iteration of the list comprehension,
# a brand new, ?immutable? object ( a list of zeros) is created.
# Immutable by virtue of the fact that there is no reference to it
# and therefore it can't be changed?????
s_grid
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
s_grid[1][1] = 99
s_grid
[[0, 0, 0, 0, 0], [0, 99, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]] # :-)

l = [0]*5
l
[0, 0, 0, 0, 0]
grid = [l for i in range(4)]
# In this form, the list comprehension is encountering a mutable
# object by virtue of the fact that there is a reference to it?
grid[1][1] = 99
grid
[[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0]] # ;-( # Is the crux of the matter that l is mutable (because it is a reference,)
# while [0]*5 is not (because it is an expression?)

my_grid = [[0, 0, 0, 0] for i in range(4)]
my_grid
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
my_grid[1][1] = 99
my_grid
[[0, 0, 0, 0], [0, 99, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

another_grid = [[0]*5]*4
# The explanations above don't seem to explain things here.
another_grid
[[0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0], [0, 0, 0, 0, 0]]
another_grid[1][1] = 99
another_grid
[[0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0], [0, 99, 0, 0, 0]]


My interpretation is that we appear to be getting a deep copy at the inner level of a multiplication but a not deep copy at the outer level. List comprehension provides us with a deep copy but only if we give it a literal (as opposed to a reference.)


Thanks, Steven, for your efforts to help.  It's very much appreciated.

alex

_______________________________________________
Tutor maillist  -  Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor

Reply via email to