3

This is my program to append list value into dictionary

lis=['a','b','c']
st=['d','e']
count=0

f={}
for s in st:
    lis.append(s) 
    f[count]=lis
    count+=1
    print f

my expected output is

{0: ['a', 'b', 'c', 'd'], 1: ['a', 'b', 'c', 'd', 'e']}

but i got

{0: ['a', 'b', 'c', 'd', 'e'], 1: ['a', 'b', 'c', 'd', 'e']}

as output. Please help me to solve this. Thanks in advance.

3 Answers3

0
lis=['a','b','c']
st=['d','e']    
{ i :lis+st[:i+1] for i in range(0,2) }
#output ={0: ['a', 'b', 'c', 'd'], 1: ['a', 'b', 'c', 'd', 'e']}
sundar nataraj
  • 8,524
  • 2
  • 34
  • 46
  • This post is being automatically flagged as low quality because it is only code. Would you expand it by adding some text to explain how it works / how it solves the problem? – gung - Reinstate Monica Jun 06 '14 at 17:50
0

You need to copy the list, because if you add it to the dictionary then modify it, it will change all the copies that exist in the dictionary.

import copy
l = ['a','b','c']
st = ['d','e']
count = 0
f = {}
for s in st:
    l.append(s)
    f[count] = copy.copy(l)
    count += 1
    print f

Output

{0: ['a', 'b', 'c', 'd']}
{0: ['a', 'b', 'c', 'd'], 1: ['a', 'b', 'c', 'd', 'e']}
Cory Kramer
  • 114,268
  • 16
  • 167
  • 218
  • you don't really need to deepcopy because the elements of the list are not references to objects. You just need to copy the list. – bcorso Jun 06 '14 at 17:32
  • 1
    why not use `f[count]=lis[:]` – Padraic Cunningham Jun 06 '14 at 17:34
  • @PadraicCunningham that would work just as well, and would save the import of the `copy` module. I guess I was just trying to make it very clear to the OP that they indeed need a copy of the list because they don't want all the keys to point to the same list as their values. – Cory Kramer Jun 06 '14 at 17:36
0

Just copy the list before putting in f so that it's value doesn't change as you add elements to the original list:

f[count]= lis[:]           # copy lis

and you get:

{0: ['a', 'b', 'c', 'd']}
{0: ['a', 'b', 'c', 'd'], 1: ['a', 'b', 'c', 'd', 'e']}

Note: Thanks to @PadraicCunningham for pointing out that [:] notation is faster than list() -- at least for small list (see What is the best way to copy a list? or How to clone or copy a list?).

Community
  • 1
  • 1
bcorso
  • 45,608
  • 10
  • 63
  • 75
  • using `f[count]=lis[:]` is a lot more effcient – Padraic Cunningham Jun 06 '14 at 17:36
  • @PadraicCunningham can you give a reference? – bcorso Jun 06 '14 at 17:37
  • @PadraicCunningham Thanks, I found a reference. Still, post another if you have a better one in mind. – bcorso Jun 06 '14 at 17:43
  • For very small lists it's the overhead related to function call that makes it slower(even a call to empty function takes some nano seconds), otherwise is slightly faster than slicing. But slicing should be preferred, because many time people use list as a variable name. (Python 2) – Ashwini Chaudhary Jun 06 '14 at 17:48
  • @PadraicCunningham I hope `l` is your case is not `range(100)`. Because `range()`'s slicing will take constant time in Python 3. – Ashwini Chaudhary Jun 06 '14 at 17:52