469,927 Members | 1,777 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,927 developers. It's quick & easy.

initialising a list of lists


This does not what I want it to do:
a = [[]] * 6
a[3].append('X')
a [['X'], ['X'], ['X'], ['X'], ['X'], ['X']]

This does what I want:
b = [[] for _ in range(6)]
b[3].append('X')
b

[[], [], [], ['X'], [], []]

The first is clear and wrong. The second is hairy and right.
Is there a way to do it clear and right?

--
Peter Kleiweg L:NL,af,da,de,en,ia,nds,no,sv,(fr,it) S:NL,de,en,(da,ia)
info: http://www.let.rug.nl/~kleiweg/ls.html
Nov 22 '05 #1
10 1835
Peter Kleiweg wrote:
This does not what I want it to do:
>>> a = [[]] * 6
>>> a[3].append('X')
>>> a [['X'], ['X'], ['X'], ['X'], ['X'], ['X']]

This does what I want:
>>> b = [[] for _ in range(6)]
>>> b[3].append('X')
>>> b

[[], [], [], ['X'], [], []]

The first is clear and wrong. The second is hairy and right.
Is there a way to do it clear and right?


http://www.python.org/doc/faq/progra...mensional-list

</F>

Nov 22 '05 #2
Peter Kleiweg wrote:
This does not what I want it to do:
>>> a = [[]] * 6
>>> a[3].append('X')
>>> a [['X'], ['X'], ['X'], ['X'], ['X'], ['X']]

This does what I want:
>>> b = [[] for _ in range(6)]
>>> b[3].append('X')
>>> b

[[], [], [], ['X'], [], []]

The first is clear and wrong. The second is hairy and right.
Is there a way to do it clear and right?


http://www.python.org/doc/faq/progra...mensional-list

</F>

Nov 22 '05 #3
Fredrik Lundh schreef op de 16e dag van de slachtmaand van het jaar 2005:
Peter Kleiweg wrote:
This does not what I want it to do:
>>> a = [[]] * 6
>>> a[3].append('X')
>>> a

[['X'], ['X'], ['X'], ['X'], ['X'], ['X']]

This does what I want:
>>> b = [[] for _ in range(6)]
>>> b[3].append('X')
>>> b

[[], [], [], ['X'], [], []]

The first is clear and wrong. The second is hairy and right.
Is there a way to do it clear and right?


http://www.python.org/doc/faq/progra...mensional-list


In other words: no there isn't.

--
Peter Kleiweg L:NL,af,da,de,en,ia,nds,no,sv,(fr,it) S:NL,de,en,(da,ia)
info: http://www.let.rug.nl/~kleiweg/ls.html
Nov 22 '05 #4
Fredrik Lundh schreef op de 16e dag van de slachtmaand van het jaar 2005:
Peter Kleiweg wrote:
This does not what I want it to do:
>>> a = [[]] * 6
>>> a[3].append('X')
>>> a

[['X'], ['X'], ['X'], ['X'], ['X'], ['X']]

This does what I want:
>>> b = [[] for _ in range(6)]
>>> b[3].append('X')
>>> b

[[], [], [], ['X'], [], []]

The first is clear and wrong. The second is hairy and right.
Is there a way to do it clear and right?


http://www.python.org/doc/faq/progra...mensional-list


In other words: no there isn't.

--
Peter Kleiweg L:NL,af,da,de,en,ia,nds,no,sv,(fr,it) S:NL,de,en,(da,ia)
info: http://www.let.rug.nl/~kleiweg/ls.html
Nov 22 '05 #5
Peter Kleiweg wrote:
This does not what I want it to do:
>>> a = [[]] * 6
>>> a[3].append('X')
>>> a [['X'], ['X'], ['X'], ['X'], ['X'], ['X']]

This does what I want:
>>> b = [[] for _ in range(6)]
>>> b[3].append('X')
>>> b
[[], [], [], ['X'], [], []]

The first is clear and wrong. The second is hairy and right.

Is there a way to do it clear
Define a function:

import copy

def init_list (count, element):
return [copy.copy (element) for i in xrange (count)]
and right?


Test it.

Daniel

Nov 22 '05 #6
Peter Kleiweg wrote:
This does not what I want it to do:
>>> a = [[]] * 6
>>> a[3].append('X')
>>> a [['X'], ['X'], ['X'], ['X'], ['X'], ['X']]

This does what I want:
>>> b = [[] for _ in range(6)]
>>> b[3].append('X')
>>> b
[[], [], [], ['X'], [], []]

The first is clear and wrong. The second is hairy and right.

Is there a way to do it clear
Define a function:

import copy

def init_list (count, element):
return [copy.copy (element) for i in xrange (count)]
and right?


Test it.

Daniel

Nov 22 '05 #7
Peter Kleiweg wrote:
http://www.python.org/doc/faq/progra...mensional-list


In other words: no there isn't.


For people who actually knows Python, a list comprehension is clear and
obviously correct.

For people who actually knows Python, your first solution is also obviously
wrong. To create a new list objects, you have to execute the list display.
New objects never appear out of the blue, and Python hardly ever copies
objects unless you tell it to do so.

</F>

Nov 22 '05 #8
Peter Kleiweg wrote:
http://www.python.org/doc/faq/progra...mensional-list


In other words: no there isn't.


For people who actually knows Python, a list comprehension is clear and
obviously correct.

For people who actually knows Python, your first solution is also obviously
wrong. To create a new list objects, you have to execute the list display.
New objects never appear out of the blue, and Python hardly ever copies
objects unless you tell it to do so.

</F>

Nov 22 '05 #9
On Wed, 16 Nov 2005 13:58:45 +0100, Peter Kleiweg wrote:

This does not what I want it to do:
>>> a = [[]] * 6
>>> a[3].append('X')
>>> a [['X'], ['X'], ['X'], ['X'], ['X'], ['X']]

This does what I want:
>>> b = [[] for _ in range(6)]
>>> b[3].append('X')
>>> b [[], [], [], ['X'], [], []]

The first is clear and wrong.
That is correct. It is wrong because you make six references to the same
empty list instead of six different empty lists.
The second is hairy and right.
I disagree. I think the second method is just as clear as the first.
Is there a way to do it clear and right?


There are lots of ways to do it right. Clarity is in the eye of the
beholder. But perhaps the clearest way is the most explicit:
c = []
for i in range(6): .... c.append([]) c[3].append('X')
c

[[], [], [], ['X'], [], []]
I can't help feeling though that this is such a common task, and so often
trips up newbies, that it deserves a built in list method. I base my
reasoning on the existence of methods like extend:

Instead of writing:

for item in seq:
L.append(item)

the Powers That Be created L.extend(seq). This isn't the only case of very
simple idioms being made even shorter in Python.

So perhaps there should be a list method that takes an integer argument
and appends that many empty lists:

d = []
d.append_empties(5)

Or even a function that does this:

def nested(numcopies, base=None, *args):
if base is None:
base = []
for i in range(numcopies):
base.append(args[:])
return base

--
Steven.

Nov 22 '05 #10
On Wed, 16 Nov 2005 13:58:45 +0100, Peter Kleiweg wrote:

This does not what I want it to do:
>>> a = [[]] * 6
>>> a[3].append('X')
>>> a [['X'], ['X'], ['X'], ['X'], ['X'], ['X']]

This does what I want:
>>> b = [[] for _ in range(6)]
>>> b[3].append('X')
>>> b [[], [], [], ['X'], [], []]

The first is clear and wrong.
That is correct. It is wrong because you make six references to the same
empty list instead of six different empty lists.
The second is hairy and right.
I disagree. I think the second method is just as clear as the first.
Is there a way to do it clear and right?


There are lots of ways to do it right. Clarity is in the eye of the
beholder. But perhaps the clearest way is the most explicit:
c = []
for i in range(6): .... c.append([]) c[3].append('X')
c

[[], [], [], ['X'], [], []]
I can't help feeling though that this is such a common task, and so often
trips up newbies, that it deserves a built in list method. I base my
reasoning on the existence of methods like extend:

Instead of writing:

for item in seq:
L.append(item)

the Powers That Be created L.extend(seq). This isn't the only case of very
simple idioms being made even shorter in Python.

So perhaps there should be a list method that takes an integer argument
and appends that many empty lists:

d = []
d.append_empties(5)

Or even a function that does this:

def nested(numcopies, base=None, *args):
if base is None:
base = []
for i in range(numcopies):
base.append(args[:])
return base

--
Steven.

Nov 22 '05 #11

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

1 post views Thread by Glen Able | last post: by
16 posts views Thread by Michael M. | last post: by
19 posts views Thread by Dongsheng Ruan | last post: by
107 posts views Thread by DaveC | last post: by
36 posts views Thread by pereges | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.