Циклические значения списка - PullRequest
0 голосов
/ 06 октября 2018

Я новичок в кодировании и пытаюсь написать простой код, который будет принимать список, скажем [1,2,3], и циклически повторять элементы n раз.Поэтому, если n = 1, я должен получить A = [3,1,2].Если n = 2, я должен получить A = [2,3,1]. Код, который я написал:

n=1
j=0
A = [1,2,3]
B = [None]*len(A)

while j<=n:
     for i in range(0,len(A)):
         B[i] = A[-1+i]
     j=j+1
print(B)

Проблема в том, что независимо от значения n, я получаю одно и то жеответ, который повторяется только один раз.Я думаю, проблема в том, что цикл циклически повторяет один и тот же B каждый раз, поэтому мне нужно сохранить новый B как что-то еще, а затем повторить цикл с новым B. Но я не могу понять, как это сделать.Любые советы будут оценены

Ответы [ 6 ]

0 голосов
/ 06 октября 2018

См. @ sacul's answer о проблеме с вашим кодом.Но list не самая подходящая структура для такого требования, поскольку каждая смена имеет сложность O ( n ).

deque ("двусторонняя"queue ") из модуля collections предоставляет эту функцию с помощью метода rotate.Этот метод работает на месте и имеет сложность O ( k ), где k - аргумент, представляющий количество вращений.Вот пример:

from collections import deque

d = deque([1,2,3])
d.rotate(2)

print(d)

deque([2, 3, 1])
0 голосов
/ 06 октября 2018

Решение на основе itertools

from itertools import cycle, islice

def roll(x, n):
    start = len(x) - n
    return islice(cycle(x), start, start + len(x))

Если мы циклически перебираем значения в x (мы бы фактически делали это максимум два раза).Затем нарежьте его так, чтобы он начинался с нужного нам элемента и включал в себя правильное количество элементов.

Возможно, он немного более эзотеричен, чем некоторые другие решения, но его стоит бросить в сумку, посколькумного альтернатив.

itertools.islice возвращает генератор.Если вы хотите напечатать результат, вам нужно преобразовать его в list.

0 голосов
/ 06 октября 2018

Более простая функция для этого:

def roll(L, n):
    n %= len(L)
    return L[-n:] + L[:-n]

A = [1,2,3]
roll(A, 1)   # [3, 1, 2]
roll(A, 2)   # [2, 3, 1]
roll(A, 3)   # [1, 2, 3]
roll(A, 4)   # [3, 1, 2]

Взятие модуля (n %= len(L)) устраняет необходимость продолжать цикл.Затем мы просто соединяем фрагмент соответствующего размера от конца списка до его начала.

0 голосов
/ 06 октября 2018

@ ответ Сакала работает, но вы были близки!Вы пропустили обновление A для следующей итерации цикла while после создания нового B.

n=1
j=0
A = [1,2,3]
B = [None]*len(A)

while j<=n:
    for i in range(0,len(A)):
        B[i] = A[-1+i]
    A = B[:] # update A so that next time B works on the new A 
    print('A is now ', A) # to debug
    j=j+1

print(B)

. Это приводит к следующим операторам печати:

A is now  [3, 1, 2]                                                                                                                   
A is now  [2, 3, 1]                                                                                                                   
[2, 3, 1] # this is what finally B is
0 голосов
/ 06 октября 2018

Не буду вдаваться в подробности, так как кто-то уже ответил на ваш вопрос. Но здесь важно отметить следующее:

A = [1, 2, 3] #Assuming that the length of the matrix you want to rotate is of length 3

If you want to cycle/rotate by 3, then you want to actually cycle/rotate by `len(A)%3` = 0
If you want to cycle/rotate by 6, then you want to actually cycle/rotate by `len(A)%6` = 0
If you want to cycle/rotate by 4, then you want to actually cycle/rotate by `len(A)%3` = 1
If you want to cycle/rotate by a number lesser than the length itself.. then just rotate it by that number!

so if you want to cycle by 2, then well.. rotate it by two.. 
0 голосов
/ 06 октября 2018

Я думаю, вы слишком усложняете это.Попробуйте изменить его на что-то вроде следующего:

n = 1
A = [1,2,3]
B = A.copy()

for _ in range(n):
    # Cycle through by concatenating the last element and all other elements together 
    B = [B[-1]]+B[0:-1]

print(B)

В случае n=1 вы получите [3, 1, 2], а n=2 даст вам [2, 3, 1]

Обратите внимание, что выпытаются сделать это реализовано в numpy.roll (я полагаю, вы спрашиваете о процессе, а не о результате, но на всякий случай)

import numpy as np

>>> np.roll(A,1)
array([3, 1, 2])
>>> np.roll(A,2)
array([2, 3, 1])
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...