Daquicker
Daquicker

Reputation: 525

Why doesn't this return the rotations of the given number?

I'll try to explain what I'm trying to do with an example:

Number = ["1","9","7"]  

So I want it to return:

[["1","9","7"],["9","7","1"],["7","1","9"]]  

What I get is:

[["7","1","9"],["7","1","9"],["7","1","9"]]

For some obscure reason it replaces my first results with the last one.

def Get_Rotations(Number):
    Rotations = []
    x = 0
    while x < len(Number):
        Number.insert(0,Number.pop())
        Rotations.append(Number)
        x += 1
    print(Rotations)
    return Rotations  

Upvotes: 1

Views: 1243

Answers (6)

wcyn
wcyn

Reputation: 4216

A simple way to do it would be:

number = ["1","9","7"]

def get_rotations(num):
    rotations = []
    for i in range(len(num)):
        rotations.append(list(num[i:] + num[0:i]))  
    return rotations

You could also use an integer instead of list of stringified integers. For example:

number = 197

def get_rotations(num):
    string_num = str(num)
    rotations = []
for i in range(len(string_num)):
    rotations.append(int(string_num[i:] + string_num[0:i])) 
    return rotations

This would give:

[197, 971, 719]

And it takes a much shorter time to execute.

Upvotes: 0

lig
lig

Reputation: 3890

Just want to suggest completely different solution.

from collections import deque

number = ['1', '9', '7']

rotator = deque(number)
rotations = [number]

for _i in range(len(number) - 1):
    rotator.rotate()
    rotations += [list(rotator)]

print(rotations)

Note that this solution is much more efficient.

Also you may or may not want to have rotator to be in the initial state after this code block run. Than you may edit this code into following

from collections import deque

number = ['1', '9', '7']

rotator = deque(number)
rotations = []

for _i in range(len(number)):
    rotations += [list(rotator)]
    rotator.rotate()

print(rotations)

Now rotator will be in initial number state. The code is a little easier to understand but you've got +1 cycle in for.

Upvotes: 3

ovgolovin
ovgolovin

Reputation: 13410

The reasons why you code doesn't work are very well explained in the other answers.

I want to point one more thing.

Insertions at the beginning of the list are quite costly. You use them here Number.insert(0,...) They have O(n) complexity (appendings are actually O(1)).

Bellow I'll show another way to do the same thing using iterators which just loop over the list with some shifts:

from itertools import cycle, islice

def rotate(L):
    ln = len(L)
    it = cycle(iter(L)) #create an overall iterator
    for _ in range(ln): #there are len(L) output lists
        yield list(islice(it,3)) #slice next 3 elements, for a list and yield the rusult
        it.next() #skip one element to start a new list shifted by one

rotate is a generator which is used to create an iterator which will yield the needed lists.

cycle and islice is from here.

Example of usage:

for el in rotate(Number):
    print el

Output:

['1', '9', '7']
['9', '7', '1']
['7', '1', '9']

Or just using list constructor:

print(list(rotate(Number)))

Output:

[['1', '9', '7'], ['9', '7', '1'], ['7', '1', '9']]

Upvotes: 0

Abhijit
Abhijit

Reputation: 63707

First Let me give you the correct answer

def Get_Rotations(Number):
    Rotations = []
    x = 0
    while len(Number):
        Rotations.append(Number.pop())
    print(Rotations)
    return Rotations

>>> Number = ["1","9","7"]
>>> Get_Rotations(Number)
['7', '9', '1']
['7', '9', '1']

Now in your case, you were doing few things wrong

  1. You were popping the Number and always inserting at the beginning.
  2. Inserting a List within a List

Do you know you can do this in a much easier way?

Number[::-1]

>>> Number[::-1]
['7', '9', '1']

Upvotes: 0

Toomai
Toomai

Reputation: 4214

When you're doing Rotations.append(Number), you're not copying Number, you're adding a reference to Number. All three of the indices in Rotations are pointing to the same object (basically like Rotations = [Number, Number, Number]), so changing Number will affect all three outputs.

Instead, create a new array, fill it with the contents of Number, and add it to Rotations.

Upvotes: 2

Achim
Achim

Reputation: 15692

You have to create copies of Number. You are manipulating the same list in each iteration and append that list three times to Rotations. Therefor you see three times Number in it's "end state".

Rotations.append(list(Number))

That minor change should do the trick! ;-)

Upvotes: 4

Related Questions