[Tutor] packing a list of lists

Dave Angel davea at ieee.org
Fri Aug 28 19:29:47 CEST 2009


kevin parks wrote:
> <div class="moz-text-flowed" style="font-family: -moz-fixed">Back to 
> python after a long long layoff. So i am running into some beginner's 
> confusion...
>
> I am trying to plot a list of numbers in gnuplot.py. To do that I am 
> trying to pack the list with an index by iterating over the list so i 
> can get something like:
>
> foo = [12, 11, 9, 6, 2, 9, 3, 8, 12, 3, 5, 6]
>
> [ [1, 12], [2, 11], [3, 9], [4, 6], [5, 2], [6, 9], [7, 3], [8, 8] ... ]
>
> So that i have x, y pairs to plot. When i print in my func i get the 
> right thing, for each item (note scaffolding) yet when i reurn the 
> whole list i just get the last pair repeated over and over.
>
> I am not sure why this is.
>
>
> def pack(in_seq):
>     out_list=[]
>     x = 1
>     ll=[1, 1]
>     for each in in_seq:
>         ll[0] = x
>         ll[1] = each
>         out_list.append(ll)
>         #print ll
>         x = x + 1
>     print out_list
>        
>
> # function declarations would go here
> def test():
>     """test function - say what this does here and skip a line
>     
>     Keyword arguments:
>     none
>     """
>
>     print
>     foo = minus(200)
>     plot_me = pack(foo)
>     #print foo
>     print
>     print plot_me
>     
>
> if __name__ == "__main__":
>     test()
>
>
>
> </div>
>
Your specific problem is that you're not building new lists, you're just 
reusing the same one each time through the loop.  The most brute-force 
fix for the problem is to use the slice operator to make a copy of the 
list before appending it to the outer list.

def pack(in_seq):
    out_list=[]
    x = 1
    ll=[1, 1]
    for each in in_seq:
        ll[0] = x
        ll[1] = each
        out_list.append(ll[:])            #make a copy of ll, and append 
that copy
        #print ll
        x = x + 1
    print out_list


pack(in_seq)


#But that's not efficient.  Better would be to construct a new list each 
time (and I'm going to avoid using variables that look like numbers):

def pack(in_seq):
    out_list=[]
    x = 1
    for each in in_seq:
        item = [x, each]
        out_list.append(item)
        #print ll
        x = x + 1
    print out_list

pack(in_seq)

#or even:

def pack(in_seq):
    out_list=[]
    x = 1
    for each in in_seq:
        out_list.append( [x, each] )
        #print ll
        x = x + 1
    print out_list

pack(in_seq)

#Note that there's a useful function enumerate which could help here:

def pack(in_seq):
    out_list=[]
    for x, each in enumerate(in_seq):
        item = [x+1, each]           #(too bad you want your integers to 
start at 1;  Python likes zero-based
        out_list.append(item)
        #print ll
    print out_list

pack(in_seq)

#and that could be simplified further

def pack(in_seq):
    out_list=[]
    for item in enumerate(in_seq):
        item = list(item)    #turn the tuple into a list
        item[0] += 1           #because you're 1-based instead of zero-based
        out_list.append(item)
        #print ll
    print out_list

pack(in_seq)

#and one more step, using zip() to combine two lists

def pack(in_seq):
    out_list = zip(xrange(1, 1+len(in_seq)), in_seq)
    print out_list

pack(in_seq)

HTH
DaveA


More information about the Tutor mailing list