TomR
TomR

Reputation: 546

Python list append returning odd results

I'm trying to create a function that returns all the circular numbers from a given number, and it's giving me an odd result. The function is:

def getcircs(mylist):
    circs=[]
    x=mylist
    y=list(x)
    dig=len(x)-1
    j=0

    circs.append(x)

    while j < dig:
        for i in range(0,dig):
            r=i+1
            g=x[r]
            y[i]=g
        y[dig]=x[0]        
        print y
        circs.append(y)
        x=list(y)
        j+=1

    print circs
    return circs

And as you can see when you run it, the lists 'y' are returning what I'm looking for, but the list 'circs' doesn't seem to have the right 'y' value appending to it. I'm wondering if it's an issue with the way Python references lists, but I can't figure it out. Thanks.

Upvotes: 1

Views: 353

Answers (2)

sberry
sberry

Reputation: 131978

In case you want to do it a simpler way (in my opinion anyway) you might benefit from using itertools.cycle here. This approach could be cleaned up too, but you get the idea:

import itertools
my_list = [1, 2, 3, 4]
cycler = itertools.cycle(my_list)
list_size = len(my_list)
for i in range(list_size):
        print [cycler.next() for j in range(list_size)] # call next on the cycler generator
        cycler.next() # skip the next number

OUTPUT

[1, 2, 3, 4]
[2, 3, 4, 1]
[3, 4, 1, 2]
[4, 1, 2, 3]

In fact, here is a one-liner for it:

print [[cycler.next() for j in range(list_size + 1)][:-1] for i in range(list_size)]

OUTOUT

[[1, 2, 3, 4], [2, 3, 4, 1], [3, 4, 1, 2], [4, 1, 2, 3]]

Upvotes: 1

Brian
Brian

Reputation: 3131

This is because lists are by reference and you re-use y. When you append y to circs, circs gets another reference to y. When you later modify y, you will see the change in each spot in circs where y was appended. Try making a copy of y and working with that.

def getcircs(mylist):
    circs=[]
    x=mylist
    y=list(x)
    dig=len(x)-1
    j=0

    circs.append(x)

    while j < dig:
        temp = y[:]
        for i in range(0,dig):
            r=i+1
            g=x[r]
            temp[i]=g
        temp[dig]=x[0]        
        print temp
        circs.append(temp)
        x=list(temp)
        j+=1

    print circs
    return circs

The line temp = y[:] just creates temp as a full slice of y, which natively produces a copy.

Upvotes: 1

Related Questions