同时从多个列表中删除元素

3
我有三个长度相同的列表和另一个列表,其中存储了我需要从这三个列表中删除元素的索引。以下是一个示例:
a = [3,4,5,12,6,8,78,5,6]
b = [6,4,1,2,8,784,43,6,2]
c = [8,4,32,6,1,7,2,9,23]

(所有元素的 len()=9)

另一个列表包含我需要从这三个列表中删除的元素的索引:

d = [8,5,3]

请注意,它已经排序。

我知道我可以使用以下方法从三个列表中逐个删除一个元素:

for indx in d:
    del a[indx]
    del b[indx]
    del c[indx]

我怎样才能用一行代码实现这个功能?


2
你需要三个单独的列表吗?如果不需要,可以将它们压缩在一起并修改一个列表:d = zip(a, b, c) - Blender
如果你需要给它们命名,为什么不将它们作为值存储在一个字典中,其键分别为'a', 'b', 和 'c'?然后只需使用for index in indices: for v in d.values(): del v[index]即可。 - abarnert
2
当出现这样的问题时,说明您的数据组织方式不正确。 - Karl Knechtel
4个回答

5

不是一行代码,而是简洁、易读且完全符合Python语言习惯的代码:

for indx in d:
    for x in a, b, c:
        del x[indx]

然而,你这样做的事实表明,也许你不应该有3个单独的列表变量,而是应该有一个包含3个列表的列表,或者一个由名称为'a'、'b'和'c'的键控的三个列表的字典。如果你真的想要一行代码:
for indx in d: a.pop(indx), b.pop(indx), c.pop(indx)

但那真的很糟糕。当你不关心值并且构建一个你不需要的元组时,你正在调用 pop

如果你想要进行简洁代码编写,你可以使用列表推导式来省略一些字符——这会增加另一个语言滥用,并构建另一个更大的对象,实际上你并不需要,就像Ioan Alexandru Cucu的答案中所示:

[x.pop(indx) for indx in d for x in a, b, c]

当然,将它分解成一个函数是将其一行写出的最好方式:
def delemall(indices, *lists):
    for index in indices:
        for x in lists:
            del x[indx]

现在,每次您需要执行此操作的300次,只需:

delemall(d, a, b, c)

这不是一行代码,但显然是最易读的解决方案。 - Ioan Alexandru Cucu
+1 给出了详细的答案,但我选择 Akavall 的答案,因为它只有一行。谢谢! - Gabriel

1
也许numpy在这种情况下很有用,如果你的三个列表是一个二维的numpy.array,删除指定列将会非常容易。
a = [3,4,5,12,6,8,78,5,6]
b = [6,4,1,2,8,784,43,6,2]
c = [8,4,32,6,1,7,2,9,23]

big_array = np.array([a,b,c])

d = [8,5,3]

结果:

>>> big_array
array([[  3,   4,   5,  12,   6,   8,  78,   5,   6],
       [  6,   4,   1,   2,   8, 784,  43,   6,   2],
       [  8,   4,  32,   6,   1,   7,   2,   9,  23]])
>>> np.delete(big_array, d, axis=1)
array([[ 3,  4,  5,  6, 78,  5],
       [ 6,  4,  1,  8, 43,  6],
       [ 8,  4, 32,  1,  2,  9]])

太好了,我不知道np.delete()命令。谢谢! - Gabriel

1
我认为您的代码已经很好了,如果要将其变成单行代码:
In [234]: for i in d: del a[i], b[i], c[i]

In [235]: a,b,c
Out[235]: ([3, 4, 5, 6, 78, 5], [6, 4, 1, 8, 43, 6], [8, 4, 32, 1, 2, 9])

但我仍然喜欢将那个for循环写在两行中 ;)


0
import operator
a = [3,4,5,12,6,8,78,5,6]
b = [6,4,1,2,8,784,43,6,2]
c = [8,4,32,6,1,7,2,9,23]
d = [8,5,3]

for _ in (operator.delitem(q,i) for q in (a,b,c) for i in d): pass

print(a,b,c)

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