Попытайтесь поместить несколько элементов из начала и конца списка
Предположим, у меня есть список таких элементов:
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)]
Это вытащит первые два элемента из начала и последних двух элементов из конца списка. Остальные предметы остаются в списке.