Ефективний спосіб повороту списку в python


263

Який найефективніший спосіб повернути список у python? Зараз у мене є щось подібне:

>>> def rotate(l, n):
...     return l[n:] + l[:n]
... 
>>> l = [1,2,3,4]
>>> rotate(l,1)
[2, 3, 4, 1]
>>> rotate(l,2)
[3, 4, 1, 2]
>>> rotate(l,0)
[1, 2, 3, 4]
>>> rotate(l,-1)
[4, 1, 2, 3]

Чи є кращий спосіб?


12
Це насправді не є зрушенням, оскільки інші мови (Perl, Ruby) використовують цей термін. Це поворот. Може питання слід оновити відповідно?
— Вінсент Фурмонд

@dzhelil Мені дуже подобається ваше оригінальне рішення, оскільки воно не вводить мутацій
— juanchito


2
Я думаю, rotateце правильне слово, ні shift.
— codeforester

2
Реальний правильну відповідь, це ви ніколи не повинні обертатися список в першу чергу. Створіть змінну "вказівник" на логічне місце у вашому списку, де ви хочете бути "головою" або "хвостом", і змініть цю змінну замість переміщення будь-якого з елементів у списку. Знайдіть оператора "modulo"% для ефективного способу "обернути" ваш покажчик навколо початку та кінця списку.
— CND

Відповіді:


280

A collections.dequeоптимізовано для витягування та натискання на обидва кінці. У них навіть є виділений rotate()метод.

from collections import deque
items = deque([1, 2])
items.append(3)        # deque == [1, 2, 3]
items.rotate(1)        # The deque is now: [3, 1, 2]
items.rotate(-1)       # Returns deque to original state: [1, 2, 3]
item = items.popleft() # deque == [2, 3]

8
Для майбутніх читачів: collections.deque rotate()швидше, ніж зрізання
— Джефф

2
Але майте на увазі, що для використання deque.rotateпотрібно dequeспочатку перетворення типу в об’єкт, яке відбувається повільніше, ніж l.append(l.pop(0)). Тож якщо у вас є предмет декесу для початку, переконайтеся, що це найшвидше. В іншому випадку використовуйте l.append(l.pop(0)).
— Перрелл

8
Щоб уточнити, deque.rotateє O (k), але тип перетворення зі списку в deque є O (n) . Отже, якщо ви починаєте зі списку, використовуючи deque.rotate - це O (n) + O (k) = O (n). l.append(l.pop(0))з іншого боку - O (1).
— Перрелл

3
@Purrell, висуваючи передню частину, це O (n). У wiki.python.org/moin/TimeComplexity це вказано як O (k), а k - кількість елементів у списку, що слідує за пунктом, що вискочив, оскільки структура даних зміщує всі наступні елементи на передню частину списку. З цієї причини лише через останній елемент можна вискочити за час O (1).
— Кірк Бойер

88

Що з просто використанням pop(0)?

list.pop([i])

Видаліть предмет у заданій позиції зі списку та поверніть його. Якщо індекс не вказаний, a.pop()вилучає та повертає останній елемент зі списку. (Квадратні дужки навколо iпідпису методу означають, що параметр є необов'язковим, а не в тому, що ви повинні вводити квадратні дужки в цьому положенні. Це позначення ви будете часто бачити в бібліотеці Python Reference.)


16
Але чи не коштувало б O (k) для видалення кожного елемента зі списку, де k - кількість решти елементів. Таким чином, загальний час буде O (N ^ 2) wiki.python.org/moin/TimeComplexity
— Pramod

5
Це насправді не відповідає на питання. Питання не в тому, щоб повернути елементи в порядку, а про створення нового списку в іншому порядку.
— користувач650261

5
ні, відповідь на запитання з використанням поп буде l.append(l.pop(0). Що якщо я не помиляюся, це O (1).
— Перрелл

4
list.pop внутрішньо викликає list_ass_slice, який використовує memmove для швидкого переміщення всіх елементів, але це все ще O (n). Дивіться сторінку github.com/python/cpython/blob/master/Objects/listobject.c та wiki.python.org/moin/TimeComplexity . Єдиний елемент, який можна вилучити зі списку пітонів за постійний час - останній.
— DRayX

2
Захищений. З docs.python.org/3/tutorial/… також можна використовувати список як чергу, де перший доданий елемент є першим отриманим елементом ("перший- вхід , перший-вихід"); однак списки не є ефективними для цієї мети. У той час як додавання та виклики з кінця списку швидкі, вставки або спливаючі елементи з початку списку повільні (тому що всі інші елементи повинні бути зміщені на один).
— SantaXL

59

Numpy може це зробити за допомогою rollкоманди:

>>> import numpy
>>> a=numpy.arange(1,10) #Generate some data
>>> numpy.roll(a,1)
array([9, 1, 2, 3, 4, 5, 6, 7, 8])
>>> numpy.roll(a,-1)
array([2, 3, 4, 5, 6, 7, 8, 9, 1])
>>> numpy.roll(a,5)
array([5, 6, 7, 8, 9, 1, 2, 3, 4])
>>> numpy.roll(a,9)
array([1, 2, 3, 4, 5, 6, 7, 8, 9])

1
Що мені подобається в тому, що іноді вниз на подачу відповідей можна знайти нові чудові скарби, як цей :)
— noamgot

Це, коли я тестував це, дуже-дуже повільно
— Пітер Гаррісон

@PeterHarrison: Оскільки ви не надаєте детальну інформацію про тестування, важко зрозуміти, що ви навіть маєте на увазі. Ця відповідь забезпечує повну інформацію про тестування та порівняння часу.
— Річард

33

Це залежить від того, що ви хочете, щоб це сталося, коли ви це зробите:

>>> shift([1,2,3], 14)

Ви можете змінити:

def shift(seq, n):
    return seq[n:]+seq[:n]

до:

def shift(seq, n):
    n = n % len(seq)
    return seq[n:] + seq[:n]

5
Примітка. Це призведе до краху для порожніх списків.
— meawoppl

n = n% len (seq) return = seq [-n:] + seq [: - n]
— користувач3303020

Чи можете ви пояснити, чому n = n% len (seq)?
— AerysS

16

Найпростіший спосіб, про який я можу придумати:

a.append(a.pop(0))

3
Це найшвидший спосіб для списків. collections.dequeшвидше, але для більшості поширених випадків довжина списку на одній ітерації або будь-який випадок декількох ітерацій a.append(a.pop(0))буде швидшою, ніж перетворення типу в deque
— Purrell

@runDOSrun - ідеальна відповідь на це питання, яке сумно закрито як дублікат. Може, ви проголосуєте за його повторне відкриття?
— Вовк

15

Якщо ви просто хочете переглядати ці набори елементів, а не будувати окрему структуру даних, подумайте про використання ітераторів для побудови виразу генератора:

def shift(l,n):
    return itertools.islice(itertools.cycle(l),n,n+len(l))

>>> list(shift([1,2,3],1))
[2, 3, 1]

11

Це також залежить від того, чи хочете ви змістити список на місце (вимкнути його), або якщо ви хочете, щоб функція повертала новий список. Тому що, за моїми тестами, щось подібне принаймні в двадцять разів швидше, ніж ваша реалізація, яка додає два списки:

def shiftInPlace(l, n):
    n = n % len(l)
    head = l[:n]
    l[:n] = []
    l.extend(head)
    return l

Насправді навіть додавання l = l[:]до верхньої частини цього, щоб оперувати копією переданого списку, все ще вдвічі швидше.

Різні реалізації з деякими термінами на http://gist.github.com/288272


3
Замість цього l[:n] = []я б пішов del l[:n]. Просто альтернатива.
— tzot

1
О так, старий добрий дель. Я часто забуваю про дель; операція зі списком, це заява, а не метод. Чи змінив py3k цю химерність, чи ми її все-таки отримали?
— keturn

2
@keturn: delвсе ще є твердженням в Py3. Однак x.__delitem__(y) <==> del x[y], якщо ви віддаєте перевагу використанню методів, l.__delitem__(slice(n))це також рівнозначно і працює в обох 2 і 3.
— martineau

9

Лише кілька зауважень щодо часу:

Якщо ви починаєте зі списку, l.append(l.pop(0))це найшвидший метод, який ви можете використовувати. Це можна показати лише за часом складності:

  • deque.rotate дорівнює O (k) (k = кількість елементів)
  • список для перетворення deque є O (n)
  • list.append і list.pop є обома O (1)

Тож якщо ви починаєте з dequeоб’єктів, ви можете deque.rotate()ціною O (k). Але, якщо початковою точкою є список, часова складність використання deque.rotate()O (n). l.append(l.pop(0)швидше при O (1).

Для ілюстрації, ось декілька зразків таймінгів на 1М ітерацій:

Методи, які потребують перетворення типів:

  • deque.rotateз об'єктом deque: 0.12380790710449219 секунд (найшвидше)
  • deque.rotateз перетворенням типу: 6.853878974914551 секунд
  • np.rollз nparray: 6.0491721630096436 секунд
  • np.rollз перетворенням типу: 27.558452129364014 секунд

Перелічіть вказані тут методи:

  • l.append(l.pop(0)): 0.32483696937561035 секунд (найшвидше)
  • " shiftInPlace": 4.819645881652832 секунд
  • ...

Використовуваний часовий код наведено нижче.


collection.deque

Показано, що створення списків із списків є O (n):

from collections import deque
import big_o

def create_deque_from_list(l):
     return deque(l)

best, others = big_o.big_o(create_deque_from_list, lambda n: big_o.datagen.integers(n, -100, 100))
print best

# --> Linear: time = -2.6E-05 + 1.8E-08*n

Якщо вам потрібно створити об’єкти deque:

1М ітерації @ 6.853878974914551 секунд

setup_deque_rotate_with_create_deque = """
from collections import deque
import random
l = [random.random() for i in range(1000)]
"""

test_deque_rotate_with_create_deque = """
dl = deque(l)
dl.rotate(-1)
"""
timeit.timeit(test_deque_rotate_with_create_deque, setup_deque_rotate_with_create_deque)

Якщо у вас вже є об'єкти deque:

1М ітерації @ 0.12380790710449219 секунд

setup_deque_rotate_alone = """
from collections import deque
import random
l = [random.random() for i in range(1000)]
dl = deque(l)
"""

test_deque_rotate_alone= """
dl.rotate(-1)
"""
timeit.timeit(test_deque_rotate_alone, setup_deque_rotate_alone)

np.roll

Якщо вам потрібно створити nparrays

1М ітерації @ 27.558452129364014 секунд

setup_np_roll_with_create_npa = """
import numpy as np
import random
l = [random.random() for i in range(1000)]
"""

test_np_roll_with_create_npa = """
np.roll(l,-1) # implicit conversion of l to np.nparray
"""

Якщо у вас вже є nparrays:

1М ітерації @ 6.0491721630096436 секунд

setup_np_roll_alone = """
import numpy as np
import random
l = [random.random() for i in range(1000)]
npa = np.array(l)
"""

test_roll_alone = """
np.roll(npa,-1)
"""
timeit.timeit(test_roll_alone, setup_np_roll_alone)

"Зсув на місці"

Не потребує перетворення типів

1М ітерації @ 4.819645881652832 секунд

setup_shift_in_place="""
import random
l = [random.random() for i in range(1000)]
def shiftInPlace(l, n):
    n = n % len(l)
    head = l[:n]
    l[:n] = []
    l.extend(head)
    return l
"""

test_shift_in_place="""
shiftInPlace(l,-1)
"""

timeit.timeit(test_shift_in_place, setup_shift_in_place)

l.append (l.pop (0))

Не потребує перетворення типів

1М ітерації @ 0,32483696937561035

setup_append_pop="""
import random
l = [random.random() for i in range(1000)]
"""

test_append_pop="""
l.append(l.pop(0))
"""
timeit.timeit(test_append_pop, setup_append_pop)

2
а list.pop () - операція постійного часу, list.pop (0) - ні . Він працює в лінійний час відносно довжини списку. Ви можете перевірити це, змінивши налаштування timeit:l = [random.random() for i in range(100000)]
— ему

1
list.pop не є операцією постійного часу. list.pop працює в O (k) час, коли k - кількість елементів, що минули видалений елемент, тому list.pop (0) - O (n). Внутрішньо list.pop використовує list_ass_slice, який використовує memmove для переміщення елементів набагато швидше, ніж ви могли коли-небудь з python, але для довгих списків це все-таки забирає багато часу. Дивіться сторінку github.com/python/cpython/blob/master/Objects/listobject.c та wiki.python.org/moin/TimeComplexity
— DRayX

Дякуємо за час (та коментарі @emu). Тож чи можна сказати, що l.append(l.pop(0))найкраще для зміщення коротких списків (близько 7 елементів) одним?
— Вовк

Знову ж таки, щодо l.append(l.pop(0))відповіді: Це запитання закрите як дублікат. Може, ви проголосуєте за його повторне відкриття?
— Вовк

8

Я також зацікавився цим і порівняв деякі запропоновані рішення з perfplot ( мій невеликий проект).

Виявляється, що

for _ in range(n):
    data.append(data.pop(0))

є на сьогоднішній день найшвидшим способом для малих зрушень n.

Для більших n,

data[n:] + data[:n]

не погано.

По суті, perfplot виконує зміну для збільшення великих масивів і вимірює час. Ось результати:

shift = 1:

введіть тут опис зображення

shift = 100:

введіть тут опис зображення


Код для відтворення сюжету:

import numpy
import perfplot
import collections


shift = 100


def list_append(data):
    return data[shift:] + data[:shift]


def shift_concatenate(data):
    return numpy.concatenate([data[shift:], data[:shift]])


def roll(data):
    return numpy.roll(data, -shift)


def collections_deque(data):
    items = collections.deque(data)
    items.rotate(-shift)
    return items


def pop_append(data):
    for _ in range(shift):
        data.append(data.pop(0))
    return data


perfplot.save(
    "shift100.png",
    setup=lambda n: numpy.random.rand(n).tolist(),
    kernels=[list_append, roll, shift_concatenate, collections_deque, pop_append],
    n_range=[2 ** k for k in range(7, 20)],
    logx=True,
    logy=True,
    xlabel="len(data)",
)

Гарний інструмент, який ви створили. Щодо l.append(l.pop(0))відповіді: Це запитання закрито як дублікат. Може, ви проголосуєте за його повторне відкриття?
— Вовк

4

Можливо, більше підходить рильффер. Це не список, хоча, ймовірно, він може вести себе досить, як список для ваших цілей.

Проблема полягає в тому, що ефективність зрушення у списку дорівнює O (n), що стає значущим для досить великих списків.

Переміщення в рингбуфер - це просто оновлення місця розташування голови, яке є O (1)


4

Для незмінної реалізації ви можете використовувати щось подібне:

def shift(seq, n):
    shifted_seq = []
    for i in range(len(seq)):
        shifted_seq.append(seq[(i-n) % len(seq)])
    return shifted_seq

print shift([1, 2, 3, 4], 1)

3

Якщо ефективність - ваша мета (цикли? Пам'ять?), Можливо, вам буде краще переглянути модуль масиву: http://docs.python.org/library/array.html

Масиви не мають накладних списків.

Що стосується чистих списків, то, що у вас є, є настільки ж хорошим, наскільки ви можете сподіватися.


3

Я думаю, ти шукаєш цього:

a.insert(0, x)

Я не бачу зв'язку між запитанням і вашою відповіддю. Чи можете ви поясніть це?
— Вовк

2

Ще одна альтернатива:

def move(arr, n):
    return [arr[(idx-n) % len(arr)] for idx,_ in enumerate(arr)]

1

Я вважаю цю модель витрат як орієнтир:

http://scripts.mit.edu/~6.006/fall07/wiki/index.php?title=Python_Cost_Model

Ваш метод складання списку та об'єднання двох підсписів - це операції лінійного часу. Я б запропонував використовувати pop, що є операцією постійного часу, наприклад:

def shift(list, n):
    for i in range(n)
        temp = list.pop()
        list.insert(0, temp)

2
оновлення: сприйміть це як кращу посилання: wiki.python.org/moin/TimeComplexity , використовуйте collections.dequeuepop та appendleft, які обидва є O (1) ops. У моїй першій відповіді вище вставте O (n).
— herrfz

1
має бутиcollections.deque
— herrfz

1

Я не знаю, чи це "ефективно", але це також працює:

x = [1,2,3,4]
x.insert(0,x.pop())

EDIT: Здрастуйте, я просто знайшов велику проблему з цим рішенням! Розглянемо наступний код:

class MyClass():
    def __init__(self):
        self.classlist = []

    def shift_classlist(self): # right-shift-operation
        self.classlist.insert(0, self.classlist.pop())

if __name__ == '__main__':
    otherlist = [1,2,3]
    x = MyClass()

    # this is where kind of a magic link is created...
    x.classlist = otherlist

    for ii in xrange(2): # just to do it 2 times
        print '\n\n\nbefore shift:'
        print '     x.classlist =', x.classlist
        print '     otherlist =', otherlist
        x.shift_classlist() 
        print 'after shift:'
        print '     x.classlist =', x.classlist
        print '     otherlist =', otherlist, '<-- SHOULD NOT HAVE BIN CHANGED!'

Метод shift_classlist () виконує той самий код, що і мій x.insert (0, x.pop ()) - рішення, otherlist - це список, не залежний від класу. Після передачі вмісту іншого списку до списку MyClass.classlist, виклик shift_classlist () також змінює список інших списків:

КОНСОЛЬНИЙ ВИХІД:

before shift:
     x.classlist = [1, 2, 3]
     otherlist = [1, 2, 3]
after shift:
     x.classlist = [3, 1, 2]
     otherlist = [3, 1, 2] <-- SHOULD NOT HAVE BIN CHANGED!



before shift:
     x.classlist = [3, 1, 2]
     otherlist = [3, 1, 2]
after shift:
     x.classlist = [2, 3, 1]
     otherlist = [2, 3, 1] <-- SHOULD NOT HAVE BIN CHANGED!

Я використовую Python 2.7. Я не знаю, чи це помилка, але я думаю, що більш ймовірно, що я щось тут неправильно зрозумів.

Хтось із вас знає, чому це відбувається?


2
Це трапляється тому, що x.classlist = otherlistзмушує x.classlistпосилатися на той самий список, що otherlistі тоді, коли ви викликаєте, x.shift_classlist()він мутує список і тому, що обидва назви посилаються на один і той же об'єкт списку. Здається, що обидва імені змінюються, оскільки вони є лише псевдонімами для одного об’єкта. Використовуйте x.classlist = otherlist[:]замість цього, щоб призначити копію списку.
— Dan D.

Гей вау! Велике спасибі! Я насправді цього не знав, і це дійсно добре знати! :)
— wese3112

1

Наступний метод є O (n) на місці з постійною допоміжною пам'яттю:

def rotate(arr, shift):
  pivot = shift % len(arr)
  dst = 0
  src = pivot
  while (dst != src):
    arr[dst], arr[src] = arr[src], arr[dst]
    dst += 1
    src += 1
    if src == len(arr):
      src = pivot
    elif dst == pivot:
      pivot = src

Зауважте, що в python такий підхід жахливо неефективний порівняно з іншими, оскільки він не може скористатись власними реалізаціями жодного з фрагментів.


ну, насправді ви можете використовувати list.pop та list.append. Це не вина мови, що ви написали функцію 12 рядків, яка є O (n), коли ви могли просто написати "l.append (l.pop (0))", який є постійним часом.
— Перрелл

l.append (l.pop (0)) є O (n) (l.pop (0) повинен зміщувати кожен елемент), таким чином, якщо ви хотіли змістити m значення, складність насправді є O (n * m). Складність запропонованого мною алгоритму становить O (n) незалежно від кількості зрушень. На практиці це повільно, оскільки стільки логіки виконується в python ops замість C (list.pop реалізований у c, див. Github.com/python/cpython/blob/master/Objects/listobject.c ).
— DRayX

1

У мене схожа річ. Наприклад, перейти на два ...

def Shift(*args):
    return args[len(args)-2:]+args[:len(args)-2]


0

Який випадок використання? Часто нам насправді не потрібен повністю зміщений масив - нам просто потрібно отримати доступ до декількох елементів у зміщеному масиві.

Отримання зрізів Python - це час виконання O (k), де k - зріз, тому обертання нарізки - це час виконання N. Команда обертання deque також є O (k). Чи можемо ми зробити краще?

Розглянемо масив, який надзвичайно великий (скажімо, такий великий, що його обчислювально було б повільно). Альтернативним рішенням було б залишити вихідний масив у спокої і просто обчислити індекс елемента, який би існував у нашому бажаному індексі після певного зрушення.

Доступ до зміщеного елемента, таким чином, стає O (1).

def get_shifted_element(original_list, shift_to_left, index_in_shifted):
    # back calculate the original index by reversing the left shift
    idx_original = (index_in_shifted + shift_to_left) % len(original_list)
    return original_list[idx_original]

my_list = [1, 2, 3, 4, 5]

print get_shifted_element(my_list, 1, 2) ----> outputs 4

print get_shifted_element(my_list, -2, 3) -----> outputs 2 

0

Після копіювання функцій список надсилається до часового списку, щоб функція pop не впливала на вихідний список:

def shift(lst, n, toreverse=False):
    templist = []
    for i in lst: templist.append(i)
    if toreverse:
        for i in range(n):  templist = [templist.pop()]+templist
    else:
        for i in range(n):  templist = templist+[templist.pop(0)]
    return templist

Тестування:

lst = [1,2,3,4,5]
print("lst=", lst)
print("shift by 1:", shift(lst,1))
print("lst=", lst)
print("shift by 7:", shift(lst,7))
print("lst=", lst)
print("shift by 1 reverse:", shift(lst,1, True))
print("lst=", lst)
print("shift by 7 reverse:", shift(lst,7, True))
print("lst=", lst)

Вихід:

lst= [1, 2, 3, 4, 5]
shift by 1: [2, 3, 4, 5, 1]
lst= [1, 2, 3, 4, 5]
shift by 7: [3, 4, 5, 1, 2]
lst= [1, 2, 3, 4, 5]
shift by 1 reverse: [5, 1, 2, 3, 4]
lst= [1, 2, 3, 4, 5]
shift by 7 reverse: [4, 5, 1, 2, 3]
lst= [1, 2, 3, 4, 5]

0

Джон Бентлі в програмуванні перлів (стовпець 2) описує елегантний та ефективний алгоритм обертання nвектора-елемента, xзалишеного iпозиціями:

Давайте розглянемо проблему як перетворення масиву abв масив ba, але припустимо також, що у нас є функція, яка повертає елементи у визначеній частині масиву. Починаючи з ab, ми повертаємо назад, aщоб дістати , зворотно дістати , а потім перевертаємо всю річ, щоб отримати , що саме . Це призводить до отримання наступного коду для обертання:arbbarbr(arbr)rba

reverse(0, i-1)
reverse(i, n-1)
reverse(0, n-1)

Це можна перекласти на Python наступним чином:

def rotate(x, i):
    i %= len(x)
    x[:i] = reversed(x[:i])
    x[i:] = reversed(x[i:])
    x[:] = reversed(x)
    return x

Демонстрація:

>>> def rotate(x, i):
...     i %= len(x)
...     x[:i] = reversed(x[:i])
...     x[i:] = reversed(x[i:])
...     x[:] = reversed(x)
...     return x
... 
>>> rotate(list('abcdefgh'), 1)
['b', 'c', 'd', 'e', 'f', 'g', 'h', 'a']
>>> rotate(list('abcdefgh'), 3)
['d', 'e', 'f', 'g', 'h', 'a', 'b', 'c']
>>> rotate(list('abcdefgh'), 8)
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h']
>>> rotate(list('abcdefgh'), 9)
['b', 'c', 'd', 'e', 'f', 'g', 'h', 'a']

0

Для списку X = ['a', 'b', 'c', 'd', 'e', 'f']та бажаного значення зсуву shift менше довжини списку ми можемо визначити функцію list_shift()як нижче

def list_shift(my_list, shift):
    assert shift < len(my_list)
    return my_list[shift:] + my_list[:shift]

Приклади,

list_shift(X,1)повертає ['b', 'c', 'd', 'e', 'f', 'a'] list_shift(X,3)прибутки['d', 'e', 'f', 'a', 'b', 'c']


1
Саме це має ОП. Ви просто змінили імена та додали твердження.
— RufusVS

Функція list_shiftу вашій відповіді ідентична функції shiftв оригінальному запитанні, тому це не відповідь на власне питання: "Чи є кращий спосіб?"
— RufusVS

0
def solution(A, K):
    if len(A) == 0:
        return A

    K = K % len(A)

    return A[-K:] + A[:-K]

# use case
A = [1, 2, 3, 4, 5, 6]
K = 3
print(solution(A, K))

Наприклад, дано

A = [3, 8, 9, 7, 6]
K = 3

функція повинна повернутися [9, 7, 6, 3, 8]. Здійснено три обертання:

[3, 8, 9, 7, 6] -> [6, 3, 8, 9, 7]
[6, 3, 8, 9, 7] -> [7, 6, 3, 8, 9]
[7, 6, 3, 8, 9] -> [9, 7, 6, 3, 8]

Для іншого прикладу

A = [0, 0, 0]
K = 1

функція повинна повернутися [0, 0, 0]

Дано

A = [1, 2, 3, 4]
K = 4

функція повинна повернутися [1, 2, 3, 4]


0

Я шукав на місці рішення цієї проблеми. Це вирішує мету в O (k).

def solution(self, list, k):
    r=len(list)-1
    i = 0
    while i<k:
        temp = list[0]
        list[0:r] = list[1:r+1]
        list[r] = temp
        i+=1
    return list

-3

для аналогічних функцій, як перехід на інші мови:

def shift(l):
    x = l[0]
    del(l[0])
    return x

1
-1: Це робить щось інше, ніж просять, і BTW також еквівалентноL.pop(0)
— 6502
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.