On 02/01/15 01:03, Alex Kleider wrote:
I don't think I understand the distinction between 'copies' and 'repeats'.
copy creates a new object with the same attributes as the original
original = [1,2,3]
copy = original[:] # slicing creates a copy
copy == original -> True
copy is original -> False
Repeats replicates the reference to the object but
does not create a new object.
reference = original # both refer to same object
reference = original -> True
reference is original -> True
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.
Deep copy is not an issue here.
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?????
It's not immutable. Whether a reference to it exists or not
has no bearing on whether it has the potential to be changed.
In fact each object created has a reference:
s_grid[0], s_grid[1], etc...
You have 5 objects, each a list of 5 zeros.
All 5 lists are mutable and all 5 are equal but not
identical (ie. not the same object).
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]] #
And as expected changing one object has no impact on the others.
And by changing it you demonstrate that the objects are not
immutable - you just mutated it!
l = [0]*5
l
[0, 0, 0, 0, 0]
You now have one list object containing 5 zeros and
a reference to it from 'l'
grid = [l for i in range(4)]
Now you have 4 more references to the same object 'l'
refers to.
# In this form, the list comprehension is encountering a mutable
# object by virtue of the fact that there is a reference to it?
No, the reference is irrelevant.
It is mutable by virtue of being a list.
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]]
You modified the object so all references (including the original 'l')
will reflect the change
# Is the crux of the matter that l is mutable (because it is a reference,)
No the objects are mutable in both examples.
mutable means you can change them. It has nothing to do with
whether there is a reference or not. (Although, if there
were truly no references the object would be destyroyed
by the garbage collector)
# while [0]*5 is not (because it is an expression?)
[0]*5 is an expression that yields a list object.
The list object is mutable. You proved that by
changing one of them.
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]]
Now you have created another list of 5 objects. Again each object has 4
zeros and they are equal but not identical. They are all mutable.
They are all referenced via my_grid. (my_grid[0],...)
my_grid[1][1] = 99
my_grid
[[0, 0, 0, 0], [0, 99, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
Again you changed(mutated) one of the objects. The
others remain untouched.
another_grid = [[0]*5]*4
Here you create a list of 4 references to the list produced by [0]*5
One list object, 4 references.
# 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]]
Again there is only one list object, so when you change it via
any of the references all the references reflect that change.
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.
No copying is going on at any point.
List comprehension provides us with a deep copy but only if we give it a
literal (as opposed to a reference.)
No, list comprehensions (and generator expressions in general)
return a sequence made up of whatever object the first
expression evaluates to. That could be an existing object
(like the one referenced by 'l' above) or a newly created
(possibly literal) object like [0, 0, 0, 0].
HTH
--
Alan G
Author of the Learn to Program web site
http://www.alan-g.me.uk/
http://www.amazon.com/author/alan_gauld
Follow my photo-blog on Flickr at:
http://www.flickr.com/photos/alangauldphotos
_______________________________________________
Tutor maillist - Tutor@python.org
To unsubscribe or change subscription options:
https://mail.python.org/mailman/listinfo/tutor