List behaviour | |
Hi all
Just wondering if someone could clarify this behaviour for me, please? Quote: Quote: Quote:
>>tasks = [[]]*6
>>tasks
[[], [], [], [], [], []] Quote: Quote: Quote:
>>tasks[0].append(1)
>>tasks
[[1], [1], [1], [1], [1], [1]]
Well what I was expecting to end up with was something like:
>>tasks
[[1], [], [], [], [], []]
I got this example from page 38 of Beginning Python.
Regards
Gabriel | | | | re: List behaviour
Gabriel a écrit : Quote:
Hi all
>
Just wondering if someone could clarify this behaviour for me, please?
> Quote: Quote:
>>>tasks = [[]]*6
>>>tasks
[[], [], [], [], [], []] Quote: Quote:
>>>tasks[0].append(1)
>>>tasks
[[1], [1], [1], [1], [1], [1]]
>
Well what I was expecting to end up with was something like:
>>tasks
[[1], [], [], [], [], []]
The problem here is that your first statement
#>>tasks = [[]]*6
creates a list (task) containing 6 references to the *same* (empty) list
object. You can check this easily using the identity test operator 'is':
#>>tasks[0] is tasks[1]
True
In fact, it's exactly as if you had written:
#>>task = []
#>>tasks = []
#>>for i in range(6):
#... tasks.append(task)
#...
If you want 6 different list objects in tasks, you can use a list
comprehension instead:
#>>tasks = [[] for i in range(6)]
#>>tasks
[[], [], [], [], [], []]
#>>tasks[0].append(1)
#>>tasks
[[1], [], [], [], [], []]
HTH | | | | re: List behaviour
Gabriel wrote: Quote:
Hi all
>
Just wondering if someone could clarify this behaviour for me, please?
> Quote: Quote:
>>>tasks = [[]]*6
>>>tasks
[[], [], [], [], [], []] Quote: Quote:
>>>tasks[0].append(1)
>>>tasks
[[1], [1], [1], [1], [1], [1]]
>
Well what I was expecting to end up with was something like:
>>tasks
[[1], [], [], [], [], []]
>
>
I got this example from page 38 of Beginning Python.
The "problem" is that all the lists inside the outer list are the same
list - you can check that with
id(tasks[0]) == id(tasks[1])
So instead of creating a list of list by the *-operator that only multiplies
the references (which is fine immutable objects like strings or numbers),
you need to explicitly create new lists, e.g. with a list-comprehension:
tasks = [[] for _ in xrange(6)]
Try this and everything will work as expected.
Diez | | | | re: List behaviour
On 15 Mag, 12:08, Gabriel <g...@dragffy.comwrote: Quote:
Hi all
>
Just wondering if someone could clarify this behaviour for me, please?
> Quote: Quote:
>tasks = [[]]*6
>tasks
>
[[], [], [], [], [], []]>>tasks[0].append(1) >
[[1], [1], [1], [1], [1], [1]]
>
Well what I was expecting to end up with was something like:
>>tasks
[[1], [], [], [], [], []]
>
I got this example from page 38 of Beginning Python.
>
Regards
>
Gabriel
The reason is that
tasks = [[]]*6
creates a list with six elements pointing to *the same* list, so when
you change one,
it shows six times.
In other words, your code is equivalent to this: Quote: Quote: Quote:
>>a = []
>>tasks = [a,a,a,a,a,a]
>>a.append(1)
>>tasks
[[1], [1], [1], [1], [1], [1]]
Insead, to create a list of lists, use the list comprehension: Quote: Quote: Quote:
>>tasks = [ [] for x in xrange(6) ]
>>tasks[0].append(1)
>>tasks
[[1], [], [], [], [], []] Ciao
-----
FB | | | | re: List behaviour
On 2008-05-15, Gabriel <gabe@dragffy.comwrote: Quote:
Hi all
>
Just wondering if someone could clarify this behaviour for me, please?
> Quote: Quote:
>>>tasks = [[]]*6
>>>tasks
[[], [], [], [], [], []] Quote: Quote:
>>>tasks[0].append(1)
>>>tasks
[[1], [1], [1], [1], [1], [1]]
>
Well what I was expecting to end up with was something like:
?>>tasks
[[1], [], [], [], [], []]
>
>
I got this example from page 38 of Beginning Python.
This is a more complicated case of
a = []
b = a
a.append(1)
print b # Will print "[1]"
This is the case, because both a and b refer to the same list data-value.
In your case, basically what you are doing is
a = [] # a is an empty list (introduced for easier explanation)
tasks = [a] # tasks is a list with 1 'a'
tasks = tasks*6 # you create 5 additional references to 'a' in 'tasks
ie tasks is now the equivalent of [a, a, a, a, a, a]. It refers to the same 'a'
list 6 times. When you print 'tasks', you actually print the same 'a' value 6
times.
in particular, tasks is **NOT**
a,b,c,d,e,f = [], [], [], [], [], [] # create 6 different empty list values
tasks2 = [a, b, c, d, e, f]
although when you print both tasks, you won't see the difference.
Next, 'tasks[0]' refers to the first list element, that is, value 'a'. To that
list you append an element. In other words, you do "a.append(1)".
However, since tasks has 6 references to the same list 'a', all its members
appear to be changed (but you are really displaying the same value 6 times).
You can query this equality with 'is':
print tasks[0] is tasks[1] # will print 'True'
print tasks2[0] is tasks2[1] # Will print 'False'
Sincerely,
Albert | | | | re: List behaviour
Bruno Desthuilliers <bruno.42.desthuilliers <atwebsiteburo.invalidwrites: Quote:
The problem here is that your first statement
>
#>>tasks = [[]]*6
>
creates a list (task) containing 6 references to the *same* (empty) list
object. You can check this easily using the identity test operator 'is':
>
Quote:
If you want 6 different list objects in tasks, you can use a list
comprehension instead:
>
#>>tasks = [[] for i in range(6)]
#>>tasks
[[], [], [], [], [], []]
#>>tasks[0].append(1)
#>>tasks
[[1], [], [], [], [], []]
>
HTH
-- http://mail.python.org/mailman/listinfo/python-list Hi Bruno
Thanks for clearing that up. Your example certainly works well, I will study
list comprehension a little more.
Many thanks
Gabriel | | | | re: List behaviour
Diez B. Roggisch <deets <atnospam.web.dewrites: Quote:
So instead of creating a list of list by the *-operator that only multiplies
the references (which is fine immutable objects like strings or numbers),
you need to explicitly create new lists, e.g. with a list-comprehension:
>
tasks = [[] for _ in xrange(6)]
>
Try this and everything will work as expected.
>
Thanks, Diez.
Thanks to all who replied to help me with this :) | | | | re: List behaviour
<bockman <atvirgilio.itwrites: Quote: Quote: Quote:
>tasks = [ [] for x in xrange(6) ]
>tasks[0].append(1)
>tasks
[[1], [], [], [], [], []] >
Thanks, Bockman | | | | re: List behaviour
On May 15, 5:08Â*pm, Gabriel <g...@dragffy.comwrote: Quote:
Hi all
>
Just wondering if someone could clarify this behaviour for me, please?
> Quote: Quote:
>tasks = [[]]*6
>tasks
>
[[], [], [], [], [], []]>>tasks[0].append(1) >
[[1], [1], [1], [1], [1], [1]]
>
Well what I was expecting to end up with was something like:
>>tasks
[[1], [], [], [], [], []]
>
I got this example from page 38 of Beginning Python.
>
Regards
>
Gabriel
As a complementary note, if you want to copy a list (probably a filled
one instead of blank ones like here) and wanted to copy a list so that
the new copy is a completely separate instance from the old copy, you
may use deepcopy (from copy import deepcopy). |  | |