References and copies

Discussion in 'Python' started by Thomas Philips, Jun 21, 2004.

1. Thomas PhilipsGuest

I want to represent an NxN matrix by a list containing N lists, each
of which has N elements. Initially the elements are set to " ". For
N=2, I write

>>>x = [" "][:]*2 #assignment creates references, not copies!
>>>x

[' ', ' ']
>>>y = [x[:]]*2
>>>y

[[' ', ' '], [' ', ' ']]
But if I assign y[0][0], I y[1,0] changes as well
>>>y[0][0]=1
>>> y

[[1, ' '], [1, ' ']]

I am clearly creating references in spite of trying not to. The
problem is completely solved by using copy.copy()
>>>x = [" "][:]*2
>>> y=[]
>>> for i in range(2):

y.append(copy.copy(x))
>>> y

[[' ', ' '], [' ', ' ']]
>>> y[0][0]=1
>>> y

[[1, ' '], [' ', ' ']]

I fail to see the error in my first attempt. Where is the fly in the
ointment?

Thomas Philips

Thomas Philips, Jun 21, 2004

2. YermatGuest

Thomas Philips a écrit :
> I want to represent an NxN matrix by a list containing N lists, each
> of which has N elements. Initially the elements are set to " ". For
> N=2, I write
>
>
>>>>x = [" "][:]*2 #assignment creates references, not copies!
>>>>x

>
> [' ', ' ']
>
>>>>y = [x[:]]*2
>>>>[...]

>
> I fail to see the error in my first attempt. Where is the fly in the
> ointment?
>
> Thomas Philips

Your trboules come from this line: y = [x[:]]*2 because you do not copy
the x twice but just assign a copy of x twice...
see the following:

>>> x = [" "]*2
>>> x

[' ', ' ']
>>> x = [" "]*2
>>> y = [x]*2
>>> y

[[' ', ' '], [' ', ' ']]
>>> id(y[0])

8303600
>>> id(y[1])

8303600
>>>
>>> y = [[" "] *2, [" "]*2]
>>> id(y[0])

8306544
>>> id(y[1])

8305424
>>>

--
Yermat

Yermat, Jun 21, 2004

3. Larry BatesGuest

You might try:

x=n*[n*[' ']]

But I always question creating arrays this
way in Python. It is normally much better
you go using .append() method.

HTH,
Larry Bates
Syscon, Inc.

"Thomas Philips" <> wrote in message
news:...
> I want to represent an NxN matrix by a list containing N lists, each
> of which has N elements. Initially the elements are set to " ". For
> N=2, I write
>
> >>>x = [" "][:]*2 #assignment creates references, not copies!
> >>>x

> [' ', ' ']
> >>>y = [x[:]]*2
> >>>y

> [[' ', ' '], [' ', ' ']]
> But if I assign y[0][0], I y[1,0] changes as well
> >>>y[0][0]=1
> >>> y

> [[1, ' '], [1, ' ']]
>
> I am clearly creating references in spite of trying not to. The
> problem is completely solved by using copy.copy()
> >>>x = [" "][:]*2
> >>> y=[]
> >>> for i in range(2):

> y.append(copy.copy(x))
> >>> y

> [[' ', ' '], [' ', ' ']]
> >>> y[0][0]=1
> >>> y

> [[1, ' '], [' ', ' ']]
>
> I fail to see the error in my first attempt. Where is the fly in the
> ointment?
>
> Thomas Philips

Larry Bates, Jun 21, 2004
4. Duncan BoothGuest

"Larry Bates" <> wrote in
news::

> You might try:
>
> x=n*[n*[' ']]
>
> But I always question creating arrays this
> way in Python. It is normally much better
> you go using .append() method.
>

Its just as well you question this as it creates a list containing n copies
of the same list.

A better way to write your example:

x = [ n*[' '] for i in range(n) ]

Duncan Booth, Jun 22, 2004
5. Thomas PhilipsGuest

1. Aaaargh.........!

2. I see, said the blind man, (as he picked up his hammer and
nail).......................

3. Thanks for the insight!

Thomas Philips

Thomas Philips, Jun 22, 2004