Попытайтесь поместить несколько элементов из начала и конца списка

Предположим, у меня есть список таких элементов:

mylist=['a','b','c','d','e','f','g','h','i']

Я хочу поместить два элемента слева (т.е. a и b) и два элемента справа (т.е. h, i). Мне нужен самый краткий способ сделать это. Я мог бы сделать это так:

for x in range(2):
    mylist.pop()
    mylist.pop(0)

Любые другие альтернативы?

Ответы

Ответ 1

С точки зрения производительности:

  • mylist = mylist[2:-2] и del mylist[:2];del mylist[-2:] эквивалентны
  • они примерно в 3 раза быстрее, чем первое решение for _ in range(2): mylist.pop(0); mylist.pop() for _ in range(2): mylist.pop(0); mylist.pop()

Код

iterations = 1000000
print timeit.timeit('''mylist=range(9)\nfor _ in range(2): mylist.pop(0); mylist.pop()''', number=iterations)/iterations
print timeit.timeit('''mylist=range(9)\nmylist = mylist[2:-2]''', number=iterations)/iterations
print timeit.timeit('''mylist=range(9)\ndel mylist[:2];del mylist[-2:]''', number=iterations)/iterations

вывод

1.07710313797e-06

3.44465017319e-07

3.49956989288e-07

Ответ 2

Вы можете отрезать новый список, сохранив старый список:

mylist=['a','b','c','d','e','f','g','h','i']
newlist = mylist[2:-2]

newlist теперь возвращает:

['c', 'd', 'e', 'f', 'g']

Вы также можете перезаписать ссылку на старый список:

mylist = mylist[2:-2]

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

То, что вы пытаетесь сделать самостоятельно, - это дружественный к памяти, а недостатком является то, что он изменяет ваш старый список, но popleft недоступен для списков в Python, это метод объекта collections.deque.

Это хорошо работает в Python 3:

for x in range(2):
    mylist.pop(0)
    mylist.pop()

В Python 2 используйте только xrange и pop:

for _ in xrange(2):
    mylist.pop(0)
    mylist.pop()

Самый быстрый способ удалить, как предлагает Martijn (это удаляет только ссылку на список, не обязательно сами элементы):

del mylist[:2]
del mylist[-2:]

Ответ 3

Если вы не хотите сохранять значения, вы можете удалить индексы:

del myList[-2:], myList[:2]

Это все равно требует, чтобы все остальные элементы были перемещены до пятен в списке. Два .popleft() также требуют этого, но по крайней мере теперь объект списка может обрабатывать перемещения за один шаг.

Новый объект списка не создается.

Демо-версия:

>>> myList = ['a','b','c','d','e','f','g','h','i']
>>> del myList[-2:], myList[:2]
>>> myList
['c', 'd', 'e', 'f', 'g']

Однако, из вашего использования popleft я сильно подозреваю, что вы вместо этого работаете с объектом collections.dequeue(). Если да, * придерживайтесь использования popleft(), поскольку это намного эффективнее, чем нарезка или del в объекте списка.

Ответ 4

Первые 2 элемента: myList[:2]
Последние 2 элемента: mylist[-2:]

Итак, myList[2:-2]

Ответ 5

Для меня это самый красивый способ сделать это с помощью функции генератора:

>> mylist=['a','b','c','d','e','f','g','h','i']
>> newlist1 = [mylist.pop(0) for idx in range(1)]
>> newlist2 = [mylist.pop() for idx in range(1)]

Это вытащит первые два элемента из начала и последних двух элементов из конца списка. Остальные предметы остаются в списке.