1

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.

2
  • What's a circular number? Commented Jun 28, 2013 at 19:35
  • Also, in a word yes. You are appending the same y list to circs multiple times. Commented Jun 28, 2013 at 19:37

2 Answers 2

1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks. I thought I had sorted out all the reference issues, clearly that wasn't the case. I appreciate the help.
1

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]]

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.