From: candide on
Let's the following code :

>>> t=[[0]*2]*3
>>> t
[[0, 0], [0, 0], [0, 0]]
>>> t[0][0]=1
>>> t
[[1, 0], [1, 0], [1, 0]]

Rather surprising, isn't it ? So I suppose all the subarrays ref�rence
the same array :

>>> id(t[0]), id(t[1]), id(t[2])
(3077445996L, 3077445996L, 3077445996L)
>>>


So what is the right way to initialize to 0 a 2D array ? Is that way
correct :


>>> t=[[0 for _ in range(2)] for _ in range(3)]

It seems there is no more trouble now :

>>> t
[[0, 0], [0, 0], [0, 0]]
>>> t[0][0]=1
>>> t
[[1, 0], [0, 0], [0, 0]]
>>>

Correct ?
From: Lie Ryan on
On 06/17/10 20:21, candide wrote:
> Let's the following code :
>
>>>> t=[[0]*2]*3
>>>> t
> [[0, 0], [0, 0], [0, 0]]
>>>> t[0][0]=1
>>>> t
> [[1, 0], [1, 0], [1, 0]]
>
> Rather surprising, isn't it ? So I suppose all the subarrays ref�rence
> the same array :
>
>>>> id(t[0]), id(t[1]), id(t[2])
> (3077445996L, 3077445996L, 3077445996L)
>>>>

Yep, you're right. They share the same subarray if you uses
multiplication to build the array.

> So what is the right way to initialize to 0 a 2D array ? Is that way
> correct :
>>>> t=[[0 for _ in range(2)] for _ in range(3)]

Right again. That's the way to go. Although if the elements are
immutable, you can create the innermost array by multiplication:

t=[[0]*2 for _ in range(3)]
From: Matteo Landi on
Yes you are. List comprehension makes you create list of lists without
reference-sharing. You should also find a recipe about that on the
python cookbook.

On Thu, Jun 17, 2010 at 12:21 PM, candide <candide(a)free.invalid> wrote:
> Let's the following code :
>
>>>> t=[[0]*2]*3
>>>> t
> [[0, 0], [0, 0], [0, 0]]
>>>> t[0][0]=1
>>>> t
> [[1, 0], [1, 0], [1, 0]]
>
> Rather surprising, isn't it ? So I suppose all the subarrays reférence the
> same array :
>
>>>> id(t[0]), id(t[1]), id(t[2])
> (3077445996L, 3077445996L, 3077445996L)
>>>>
>
>
> So what is the right way to initialize to 0 a 2D array ? Is that way correct
>  :
>
>
>>>> t=[[0 for _ in range(2)] for _ in range(3)]
>
> It seems there is no more trouble now :
>
>>>> t
> [[0, 0], [0, 0], [0, 0]]
>>>> t[0][0]=1
>>>> t
> [[1, 0], [0, 0], [0, 0]]
>>>>
>
> Correct ?
> --
> http://mail.python.org/mailman/listinfo/python-list
>



--
Matteo Landi
http://www.matteolandi.net/
From: Boris Borcic on
candide wrote:
>
> So what is the right way to initialize to 0 a 2D array ? Is that way
> correct :
>
>
> >>> t=[[0 for _ in range(2)] for _ in range(3)]

That's overkill :) You can skip the inner loop by using a list display, eg

t=[[0,0] for _ in range(3)]

>
> It seems there is no more trouble now :
>
> >>> t
> [[0, 0], [0, 0], [0, 0]]
> >>> t[0][0]=1
> >>> t
> [[1, 0], [0, 0], [0, 0]]
> >>>
>
> Correct ?


From: J Kenneth King on
candide <candide(a)free.invalid> writes:

> Let's the following code :
>
>>>> t=[[0]*2]*3
>>>> t
> [[0, 0], [0, 0], [0, 0]]
>>>> t[0][0]=1
>>>> t
> [[1, 0], [1, 0], [1, 0]]
>
> Rather surprising, isn't it ?

Not at all, actually.

I'd be surprised if the multiplication operator was aware of object
constructors. Even arrays are "objects" in Python. Should the
multiplication operator know how to instantiate three arrays from a
single array instance? What about an instance of a user-defined class?

> So I suppose all the subarrays reférence
> the same array :
>
>>>> id(t[0]), id(t[1]), id(t[2])
> (3077445996L, 3077445996L, 3077445996L)
>>>>
>

As they should.

>
> So what is the right way to initialize to 0 a 2D array ? Is that way
> correct :
>
>
>>>> t=[[0 for _ in range(2)] for _ in range(3)]
>
> It seems there is no more trouble now :
>
>>>> t
> [[0, 0], [0, 0], [0, 0]]
>>>> t[0][0]=1
>>>> t
> [[1, 0], [0, 0], [0, 0]]
>>>>
>
> Correct ?

>>> 2d_zero_vector = lambda len: [[0, 0] for _ in range(len)]
>>> t = 2d_zero_vector(3)
>>> print t
[[0, 0], [0, 0], [0, 0]]
>>> t[0][0] = 1
>>> print t
[[1, 0], [0, 0], [0, 0], [0, 0]]

(Of course, if you're doing matrix math you'll probably want to work
with numpy which has a function for doing just this)