# [Tutor] Making Doubly Linked List with Less Lines of Code.

Alex Kleider akleider at sonic.net
Fri Jan 2 02:03:18 CET 2015

```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

```