有没有更好的方法可以删除列表的最后N个元素?
for i in range(0,n):
lst.pop( )
适用于 n >= 1
>>> L = [1,2,3, 4, 5]
>>> n=2
>>> del L[-n:]
>>> L
[1, 2, 3]
如果您希望删除最后n个元素,换句话说,保留前len - n个元素:
lst = lst[:len(lst)-n]
注意: 这不是一个内存操作,它会创建一个浅拷贝。
- Corey O.lst = range(1, 11) lst [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] n = 5 lst = lst[:n - 1] lst [1, 2, 3, 4]
正如 Vincenzooo 所说,当 n==0
时,Pythonic 的 lst[:-n]
无法正常工作。
对于所有的 n>=0
,以下方法都有效:
lst = lst[:-n or None]
我喜欢这个解决方案,因为它在英语中也很容易理解:“返回省略最后n个元素的切片或没有(如果不需要省略)”。
这个解决方案之所以可行,是因为:
x or y
的计算结果为 x
当 x
逻辑上为真时(例如,当它不是 0
、""
、False
、None
等),否则为 y
。因此,当 n!=0
时,-n or None
是 -n
,当 n==0
时,-n or None
是 None
。None
等同于省略该值,因此 lst[:None]
和 lst[:]
是相同的 (参见这里)。正如 @swK 所指出的那样,这个解决方案创建了一个新列表(但除非其他地方引用了旧列表,否则立即丢弃旧列表),而不是直接编辑原始列表。在性能方面,通常这不是一个问题,因为一次性创建一个新列表通常比逐个删除一个元素要快(除非 n
<<len(lst)
)。在空间方面也通常不是问题,因为通常列表的成员所占的空间比列表本身更大(除非它是由像bytes
这样的小对象组成的列表,或者该列表具有许多重复的条目)。请注意,这个解决方案与原始帖子中的解决方案并不完全相同。如果其他变量引用了原始列表,则此解决方案不会修改(缩短)其他副本。
一个可能的解决方案(与我的原始解决方案相同风格),适用于 n>=0
但: a) 不创建列表的副本; b) 同时影响对同一列表的其他引用,可以是以下内容:
lst[-n:n and None] = []
这肯定不可读,不应该使用。实际上,即使是我的原始解决方案,也需要对语言的理解过多,才能被每个人快速阅读并明确理解。我不会在任何真正的代码中使用其中任何一个,我认为最好的解决方案是由@wonder.mice提出的:a[len(a)-n:] = []
。
lst
,在运行上述代码后,它仍将指向旧的 lst
,而不是包含 n
个较少元素的新浅拷贝(这可能是预期的行为,也可能不是)。 - jamylak我看到这个问题早就被问过了,但是没有一个答案能够满足我的需求。如果我们想要获取原始列表中除最后N个元素外的所有元素,可以使用以下代码:list[:-n]
。如果需要处理n
可能为0
的情况,则可以使用list[:-n or None]
。
>>> a = [1,2,3,4,5,6,7]
>>> b = a[:-4]
>>> b
[1, 2, 3]
>>> a
[1, 1, 2, 3, 4, 5, 7]
就是这么简单。
就试着像这样删除它。
del list[-n:]
lst = lst[:len(lst)-n]
更好的方法吗? - zheyuanWanga[len(a)-n:] = []
或者这样:
del a[len(a)-n:]
这种方式更快,因为它实际上是从现有数组中删除项。相反地 (a = a[:len(a)-1]
) 则创建一个新的列表对象,效率较低。
>>> timeit.timeit("a = a[:len(a)-1]\na.append(1)", setup="a=range(100)", number=10000000)
6.833014965057373
>>> timeit.timeit("a[len(a)-1:] = []\na.append(1)", setup="a=range(100)", number=10000000)
2.0737061500549316
>>> timeit.timeit("a[-1:] = []\na.append(1)", setup="a=range(100)", number=10000000)
1.507638931274414
>>> timeit.timeit("del a[-1:]\na.append(1)", setup="a=range(100)", number=10000000)
1.2029790878295898
如果0<n
,可以使用a[-n:] = []
或del a[-n:]
,这甚至更快。l=range(4)
for n in [2,1,0]: #test values for numbers of points to cut
print n,l[:len(l)-n]
n=0
,但被接受的答案与你的解决方案相同。 - jamylak
list
,否则你将无法使用内置的list
类。 - jamylak