Ефективний спосіб повороту списку в 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.