从列表的开头和结尾弹出多个项目

Ehs*_*n88 23 python arrays list

假设我有一个这样的项目列表:

mylist=['a','b','c','d','e','f','g','h','i']
Run Code Online (Sandbox Code Playgroud)

我想从左边(ie ab)弹出两个项目,从右边弹出两个项目(即h,i).我想要最简洁,干净的方式来做到这一点.我可以这样做自己:

for x in range(2):
    mylist.pop()
    mylist.pop(0)
Run Code Online (Sandbox Code Playgroud)

还有其他选择吗?

bol*_*old 23

从性能的角度来看:

  • mylist = mylist[2:-2]并且del mylist[:2];del mylist[-2:]是等价的
  • 它们比第一个解决方案快3倍左右 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
Run Code Online (Sandbox Code Playgroud)

产量

1.07710313797e-06

3.44465017319e-07

3.49956989288e-07


Aar*_*all 11

您可以切出一个新列表,保持旧列表不变:

mylist=['a','b','c','d','e','f','g','h','i']
newlist = mylist[2:-2]
Run Code Online (Sandbox Code Playgroud)

newlist 现在返回:

['c', 'd', 'e', 'f', 'g']
Run Code Online (Sandbox Code Playgroud)

您也可以覆盖对旧列表的引用:

mylist = mylist[2:-2]
Run Code Online (Sandbox Code Playgroud)

上述两种方法都将使用比下面更多的内存.

你自己试图做的是内存友好,它的缺点是它改变你的旧列表,但popleft不适用于Python中的列表,它是collections.deque对象的一种方法.

这在Python 3中运行良好:

for x in range(2):
    mylist.pop(0)
    mylist.pop()
Run Code Online (Sandbox Code Playgroud)

在Python 2中,仅使用xrange和pop:

for _ in xrange(2):
    mylist.pop(0)
    mylist.pop()
Run Code Online (Sandbox Code Playgroud)

Martijn建议删除最快的方法,(这只删除列表对项目的引用,不一定是项目本身):

del mylist[:2]
del mylist[-2:]
Run Code Online (Sandbox Code Playgroud)


Mar*_*ers 7

如果您不想保留值,可以删除索引:

del myList[-2:], myList[:2]
Run Code Online (Sandbox Code Playgroud)

这仍然需要将所有剩余项目移动到列表中的位置.两个.popleft()调用也需要这个,但至少现在list对象可以一步处理移动.

没有创建新的列表对象.

演示:

>>> myList = ['a','b','c','d','e','f','g','h','i']
>>> del myList[-2:], myList[:2]
>>> myList
['c', 'd', 'e', 'f', 'g']
Run Code Online (Sandbox Code Playgroud)

但是,从你的使用popleft我强烈怀疑你,而是使用一个collections.dequeue()对象.如果是这样,*坚持使用popleft(),因为这比切片或del列表对象更有效.