[Tutor] reg. list update

Peter Otten __peter__ at web.de
Mon Apr 17 16:58:30 EDT 2017


Rasika Sapate via Tutor wrote:

> Dear Python group,
> I had written following code.
> 
> super = []
> sub = [""]*3
> other = ["a","b","c","d"]
> sub[0] = "hi"
> sub[1] = "hello"
> for item in other:
>     sub[2] = item
>     super.append(sub)
> for item in super:
>     print item
> 
> 
> Output :
> ['hi', 'hello', 'd']
> ['hi', 'hello', 'd']
> ['hi', 'hello', 'd']
> ['hi', 'hello', 'd']
> 
> 
> Expected output:
> ['hi', 'hello', 'a]
> ['hi', 'hello', 'b']
> ['hi', 'hello', 'c']
> ['hi', 'hello', 'd']
> 
> 
> Is there anything wrong in this code or any feature of python?

When you replace an item in a list you don't magically copy that list, so in 
a for loop

>>> outer = []
>>> inner = [1, 2, 3]
>>> for item in "abc":
...    inner[2] = item
...    outer.append(inner)
... 
>>>

You append the same list three time to outer

>>> outer[0] is inner
True
>>> outer[2] is inner
True

and inner[2] holds the last value you assigned to it. What you want is a new 
list on each iteration, and one way to get that when the inner list is long 
is list concatenation with the + operator:

>>> outer = []
>>> inner_start = [1, 2]
>>> for item in "abc":
...     outer.append(inner_start + [item])
... 
>>> outer[0] is outer[2]
False
>>> outer
[[1, 2, 'a'], [1, 2, 'b'], [1, 2, 'c']]

In your case with only three items I recommend that you use a list literal:

>>> outer = []
>>> for item in "abc":
...     outer.append([1, 2, item])
... 
>>> outer
[[1, 2, 'a'], [1, 2, 'b'], [1, 2, 'c']]

Python has a concise way to spell those append-only loops which is called 
list comprehension and looks like this:

>>> [[1, 2, item] for item in "abc"]
[[1, 2, 'a'], [1, 2, 'b'], [1, 2, 'c']]




More information about the Tutor mailing list