如何从列表中删除每个第n个元素?

20

我已经阅读了这篇帖子:Python:通过删除每n个元素来构建新列表,但出于某种原因它对我不起作用:

我尝试了以下方法:

def drop(mylist, n):
    del mylist[0::n]
    print(mylist)

这个函数接受一个列表和一个 n。它通过从列表中使用 n 步来移除每个第 n 个元素,并打印结果。

下面是我的函数调用:

drop([1,2,3,4],2)

错误输出:
[2, 4] 而不是 [1, 3]


然后我尝试了上面链接中的一个变体:

def drop(mylist, n):
    new_list = [item for index, item in enumerate(mylist) if index % n != 0]
    print(new_list)

再次,函数调用:

drop([1,2,3,4],2)

代码返回错误的结果:[2, 4],而不是正确的结果:[1, 3]


如何正确地从列表中删除每个第n个元素?


1
答案是正确的。根据你所说,你假设索引编号从1开始,但系统从0开始计数。 - naitoon
5个回答

36

假设你有以下列表:

a = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

如果您想要删除每 k 个元素,可以这样操作:

del a[k-1::k]
例如,当k = 3时,当前列表现在为:
[1, 2, 4, 5, 7, 8, 10]

1
这个解决方案让我大吃一惊!哇! - ShellZero

9
输出是正确的,你正在删除索引为0、n、2n等的元素。因此1和3被删除了,2和4保留下来了。所以如果你想要打印出索引为0、n、2n等的元素,只需要写:
print(mylist[::n])

4
在你的第一个函数中,mylist[0::n]的结果是[1, 3],因为0::n表示第一个元素是0,其他元素是每隔n个元素取一个。正如Daniel所建议的那样,你可以使用mylist[::n],这意味着每隔n个元素取一个。
在你的第二个函数中,索引从0开始,0 % 0是0,因此它不会复制第一个元素。对于第三个元素也是一样的(2 % 2是0)。所以你需要做的就是new_list = [item for index, item in enumerate(mylist) if (index + 1) % n != 0] 提示:在类似这样的函数中,你可能想使用return而不是print()

2

您的第一种方法看起来不错 - 如果您想删除元素1、1+n、1+2n等(似乎是这种情况),则只需调整起始索引即可:

lst = list(range(1, 5))
del lst[1::2]
print(lst)

1
另一种方法是生成一个只包含所需元素的新列表。
newList = [x for i, x in enumerate(myList) if i%n !=0]

如果n是5,这将返回一个包含元素[1,2,3,4,6,7,8,9,11...]的列表。 这种方法的优点是保留了原始列表,如果您要重复使用数据,则非常有用。但是,如果您担心节省内存,那么可能不是最佳选择。

你的代码没有按照预期执行,而是输出了 [2, 3, 4, 5, 7, 8, 9, 10, 12, 13, 14, 15] - bit_scientist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接