using "*" to make a list of lists with repeated (and independent) elements

T

TP

Hi everybody,

I have tried, naively, to do the following, so as to make lists quickly:
[3, 0]

All is working fine, so I extended the technique to do:
a=[[0]*3]*2
a [[0, 0, 0], [0, 0, 0]]
a[0][0]=2
a
[[2, 0, 0], [2, 0, 0]]

The behavior is no more expected!
The reason is probably that in the first case, 0 is an integer, not a list,
so Python copies two elements that are independent.
In the second case, the elements are [0,0,0], which is a list; when Python
copies a list, he copies in fact the *pointer* to the list, such that we
obtain this apparently strange behavior.

Is it the correct explanation?
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?

Thanks,

TP
 
I

Ian Kelly

Hi everybody,

I have tried, naively, to do the following, so as to make lists quickly:
a=[0]*2
a [0, 0]
a[0]=3
a
[3, 0]

All is working fine, so I extended the technique to do:
a=[[0]*3]*2
a [[0, 0, 0], [0, 0, 0]]
a[0][0]=2
a
[[2, 0, 0], [2, 0, 0]]

The behavior is no more expected!
The reason is probably that in the first case, 0 is an integer, not a list,
so Python copies two elements that are independent.
In the second case, the elements are [0,0,0], which is a list; when Python
copies a list, he copies in fact the *pointer* to the list, such that we
obtain this apparently strange behavior.

Mostly correct. When you do [foo] * 3 it extends the list with the
*same objects* no matter what type they are. In the case of integers,
it doesn't matter that it's the same objects, because integers are
immutable. Lists are mutable, however, and so it becomes apparent
that the same objects are repeated when you try to modify one of the
lists.
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?

Use a list comprehension:

a = [[0] * 3 for _ in range(2)]

This way the expression `[0] * 3` is re-evaluated at each position in
the outer list, rather than evaluated just once and then copied.
 
8

88888 Dihedral

TPæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ5時25分04秒寫é“:
Hi everybody,



I have tried, naively, to do the following, so as to make lists quickly:



[0, 0]

[3, 0]



All is working fine, so I extended the technique to do:



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

[[2, 0, 0], [2, 0, 0]]



The behavior is no more expected!

The reason is probably that in the first case, 0 is an integer, not a list,

so Python copies two elements that are independent.

In the second case, the elements are [0,0,0], which is a list; when Python

copies a list, he copies in fact the *pointer* to the list, such that we

obtain this apparently strange behavior.



Is it the correct explanation?

In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"

without this behavior?



Thanks,



TP

def zeros(m,n):
for i in xrange(m):
for j in xrange(n):
a[j]=0
return a
a=zeros(3,2)
a [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

I think this is what you want.
 
8

88888 Dihedral

Paul Rubinæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ5時43分58秒寫é“:
TP said:
copies a list, he copies in fact the *pointer* to the list ....
Is it the correct explanation?



Yes, that is correct.


In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?

a = [[0]*3 for i in xrange(2)]
a[0][0]=2
a

[[2, 0, 0], [0, 0, 0]]

I used numpy before.

Python is not lisp but python can emulate the lisp behaviors.
 
8

88888 Dihedral

88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
Paul Rubinæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ5時43分58秒寫é“:
copies a list, he copies in fact the *pointer* to the list ....
Is it the correct explanation?
Yes, that is correct.
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]

[[2, 0, 0], [0, 0, 0]]



I used numpy before.



Python is not lisp but python can emulate the lisp behaviors.

def zeros(m,n):
a=[]
for i in xrange(m):
a.append([0]*n)
return a

If one wants to tranlate to C, this is the style.
 
T

Tim Chase

88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]
a[0][0]=2
a
[[2, 0, 0], [0, 0, 0]]

def zeros(m,n):
a=[]
for i in xrange(m):
a.append([0]*n)
return a

If one wants to tranlate to C, this is the style.

But this is Python, so why the heck would anybody want to emulate
*C* style? It could also be written in an assembly-language style,
COBOL style, or a Fortran style...none of which are particularly
valuable.

Besides, a C-style would allocate a single array of M*N slots and
then calculate 2d offsets into that single array. :p

-tkc
 
8

88888 Dihedral

Tim Chaseæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時44分42秒寫é“:
88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]
a[0][0]=2
a
[[2, 0, 0], [0, 0, 0]]
def zeros(m,n):

for i in xrange(m):
a.append([0]*n)

return a
If one wants to tranlate to C, this is the style.



But this is Python, so why the heck would anybody want to emulate

*C* style? It could also be written in an assembly-language style,

COBOL style, or a Fortran style...none of which are particularly

valuable.



Besides, a C-style would allocate a single array of M*N slots and

then calculate 2d offsets into that single array. :p



-tkc

I don't think a lot programmers can write assembly programs well
for different instruction sets of cpus.

Of course if GCC was not supportd in manny platforms free
of charge, then I won't recommend this style of
programming in python.
 
8

88888 Dihedral

Tim Chaseæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時44分42秒寫é“:
88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]
a[0][0]=2
a
[[2, 0, 0], [0, 0, 0]]
def zeros(m,n):

for i in xrange(m):
a.append([0]*n)

return a
If one wants to tranlate to C, this is the style.



But this is Python, so why the heck would anybody want to emulate

*C* style? It could also be written in an assembly-language style,

COBOL style, or a Fortran style...none of which are particularly

valuable.



Besides, a C-style would allocate a single array of M*N slots and

then calculate 2d offsets into that single array. :p



-tkc

I don't think a lot programmers can write assembly programs well
for different instruction sets of cpus.

Of course if GCC was not supportd in manny platforms free
of charge, then I won't recommend this style of
programming in python.
 
8

88888 Dihedral

Tim Chaseæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時44分42秒寫é“:
88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]
a[0][0]=2
a
[[2, 0, 0], [0, 0, 0]]
def zeros(m,n):

for i in xrange(m):
a.append([0]*n)

return a
If one wants to tranlate to C, this is the style.



But this is Python, so why the heck would anybody want to emulate

*C* style? It could also be written in an assembly-language style,

COBOL style, or a Fortran style...none of which are particularly

valuable.



Besides, a C-style would allocate a single array of M*N slots and

then calculate 2d offsets into that single array. :p



-tkc

a=[1, 2,3]
b=[a]*4
print b
a[1]=4
print b

I thnik this is very clear about the situation in entangled references.
 
8

88888 Dihedral

Tim Chaseæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時44分42秒寫é“:
88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]
a[0][0]=2
a
[[2, 0, 0], [0, 0, 0]]
def zeros(m,n):

for i in xrange(m):
a.append([0]*n)

return a
If one wants to tranlate to C, this is the style.



But this is Python, so why the heck would anybody want to emulate

*C* style? It could also be written in an assembly-language style,

COBOL style, or a Fortran style...none of which are particularly

valuable.



Besides, a C-style would allocate a single array of M*N slots and

then calculate 2d offsets into that single array. :p



-tkc

a=[1, 2,3]
b=[a]*4
print b
a[1]=4
print b

I thnik this is very clear about the situation in entangled references.
 
R

Ramchandra Apte

88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]
a[0][0]=2
a
[[2, 0, 0], [0, 0, 0]]
def zeros(m,n):

for i in xrange(m):
a.append([0]*n)

return a
If one wants to tranlate to C, this is the style.



But this is Python, so why the heck would anybody want to emulate

*C* style? It could also be written in an assembly-language style,

COBOL style, or a Fortran style...none of which are particularly

valuable.



Besides, a C-style would allocate a single array of M*N slots and

then calculate 2d offsets into that single array. :p



-tkc

88888 Dihedral is a bot.
 
R

Ramchandra Apte

88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]
a[0][0]=2
a
[[2, 0, 0], [0, 0, 0]]
def zeros(m,n):

for i in xrange(m):
a.append([0]*n)

return a
If one wants to tranlate to C, this is the style.



But this is Python, so why the heck would anybody want to emulate

*C* style? It could also be written in an assembly-language style,

COBOL style, or a Fortran style...none of which are particularly

valuable.



Besides, a C-style would allocate a single array of M*N slots and

then calculate 2d offsets into that single array. :p



-tkc

88888 Dihedral is a bot.
 
8

88888 Dihedral

On 09/26/12 17:28, 88888 Dihedral wrote:
88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]
[[2, 0, 0], [0, 0, 0]]
def zeros(m,n):
for i in xrange(m):
If one wants to tranlate to C, this is the style.
But this is Python, so why the heck would anybody want to emulate
*C* style? It could also be written in an assembly-language style,
COBOL style, or a Fortran style...none of which are particularly
valuable.

Besides, a C-style would allocate a single array of M*N slots and
then calculate 2d offsets into that single array. :p
-tkc



88888 Dihedral is a bot.

Don't you get it why I avoided the lambda one liner as a functon.

I prefer the def way with a name chosen.
 
8

88888 Dihedral

On 09/26/12 17:28, 88888 Dihedral wrote:
88888 Dihedralæ–¼ 2012å¹´9月27日星期四UTC+8上åˆ6時07分35秒寫é“:
In these conditions, how to make this list [[0,0,0],[0,0,0]] with "*"
without this behavior?
a = [[0]*3 for i in xrange(2)]
[[2, 0, 0], [0, 0, 0]]
def zeros(m,n):
for i in xrange(m):
If one wants to tranlate to C, this is the style.
But this is Python, so why the heck would anybody want to emulate
*C* style? It could also be written in an assembly-language style,
COBOL style, or a Fortran style...none of which are particularly
valuable.

Besides, a C-style would allocate a single array of M*N slots and
then calculate 2d offsets into that single array. :p
-tkc



88888 Dihedral is a bot.

Don't you get it why I avoided the lambda one liner as a functon.

I prefer the def way with a name chosen.
 
I

Ian Kelly

Don't you get it why I avoided the lambda one liner as a functon.

I prefer the def way with a name chosen.

Certainly, but the Bresenham line algorithm is O(n), which is why it
is so superior to quicksort that is O(n log n). Of course you might
try the Capo Ferro optimization, but I find that Thibault cancels out
Capo Ferro, don't you?
 
C

Chris Angelico

Certainly, but the Bresenham line algorithm is O(n), which is why it
is so superior to quicksort that is O(n log n). Of course you might
try the Capo Ferro optimization, but I find that Thibault cancels out
Capo Ferro, don't you?

Unless ...

class Agrippa(object):
students = []
def __init__(self):
students.append(self)

enemy = Agrippa()

ChrisA
(maybe I'm pushing this a bit too far)
 
8

88888 Dihedral

Certainly, but the Bresenham line algorithm is O(n), which is why it

is so superior to quicksort that is O(n log n). Of course you might

try the Capo Ferro optimization, but I find that Thibault cancels out

Capo Ferro, don't you?

OK! I'll illustrate the lazy aspect of the python interpreter furthermore.

a=[1,2,3]
b=[a]*4 # different from a sliced copy as [list(a)]*4
print b
a[1]=4
print b
#-----
a=666 # type morphed
print b
 
8

88888 Dihedral

Certainly, but the Bresenham line algorithm is O(n), which is why it

is so superior to quicksort that is O(n log n). Of course you might

try the Capo Ferro optimization, but I find that Thibault cancels out

Capo Ferro, don't you?

OK! I'll illustrate the lazy aspect of the python interpreter furthermore.

a=[1,2,3]
b=[a]*4 # different from a sliced copy as [list(a)]*4
print b
a[1]=4
print b
#-----
a=666 # type morphed
print b
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,969
Messages
2,570,161
Members
46,705
Latest member
Stefkari24

Latest Threads

Top