一次删除多个数组中给定值的所有匹配项

时间:2013-07-19 10:07:48

标签: python arrays pop

我有四个数组,比如A,B,C和D,它们的大小相同,并且我想删除它们中的所有0。如果A有零,B,C和D也有一个,在同一位置。所以我想要绕过A:

的元素
for n in range(NumElements):
    if A[n]==0:
       A.pop(n)
       B.pop(n)
       C.pop(n)
       D.pop(n)

当然,这不起作用,因为从数组中弹出0会减小它们的大小,所以我最终尝试访问A [NumElements-1],而现在A只是NumElements-m long。我知道我应该使用数组副本,但数组很长,我想保持低内存消耗,因为我在Java虚拟机中工作(不要问:(((()。另外,我想要一种有效的方法,但最重要的是可读(这些代码必须由像我这样的Python文盲维护,所以我需要亲吻)。谢谢,

deltaquattro

6 个答案:

答案 0 :(得分:5)

a,b,c,d = [filter(lambda i: i != 0, l) for l in [a,b,c,d]]

过滤每个列表,删除非0的元素。

编辑,

只是为了解释发生了什么

Filter通过将函数应用于列表中的所有内容来获取表达式并“过滤”列表,所有内容都不会返回True。

Lambda是函数的简写

所以

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

def is_even(x):
    return x % 2 == 0
filter(is_even, a)

答案 1 :(得分:4)

如果它们在同一个地方都有零,那么在反向中遍历索引并从每个列表中删除该索引:

for i in reversed(range(NumElements)):
    if not A[i]:
        del A[i], B[i], C[i], D[i]

通过反向循环遍历列表,可以使索引保持稳定(仅删除元素过去当前索引,仅缩小列表的尾部)。既然你没有使用 list.pop()的返回值(你得到的只是0,对吗?),你也可以只使用del而是列表索引。

我在这里使用reversed(range(NumElements))而不是计算更加费劲的range(NumElements - 1, -1, -1);它同样有效但更具可读性。 reversed() function返回一个迭代器,非常有效地处理反转的数字序列。在Python 2上,您可以对xrange()执行相同的操作:

for i in reversed(xrange(NumElements)):

演示:

>>> A = [1, 2, 0, 4, 5, 0]
>>> B = [2, 4, 0, 10, 9, 0]
>>> C = [5, 3, 0, 10, 8, 0]
>>> D = [10, 3, 0, 1, 34, 0]
>>> for i in reversed(range(NumElements)):
...     if not A[i]:
...         del A[i], B[i], C[i], D[i]
... 
>>> A, B, C, D
([1, 2, 4, 5], [2, 4, 10, 9], [5, 3, 10, 8], [10, 3, 1, 34])

答案 2 :(得分:2)

我认为你可以这样做。我不知道它是否足够pythonic。

A = [1, 2, 4, 0]
B = [6, 0, 4, 3, 9]
C = [12, 5, 32, 0, 90]

for row in [A, B, C]:
    for i, v in enumerate(row):
        if v == 0: del row[i]

或者,如果您确定所有列表中的零索引相等:

for i in range(len(A) - 1, -1, -1):
    if A[i] == 0:
        for row in [A, B, C]:
             del row[i]   

答案 3 :(得分:2)

从另一端开始工作!

for n in range(NumElements-1,-1,-1):
    if A[n]==0:
       A.pop(n)
       B.pop(n)
       C.pop(n)
       D.pop(n)

答案 4 :(得分:1)

看看我的另一个答案List accessing in Python。您可以遍历列表A并将0的索引存储在临时列表中,然后弹出它们。

答案 5 :(得分:1)

这可能是一个黑客,但它很简单,它的工作原理

>>> a = [1,2,3]
>>> b = [1,10,99]
>>> c = [1,87,22]
>>> d = []
>>> d.extend([a,b,c])
>>> to_remove = 1
>>> [i.remove(to_remove) for i in d]
>>> d
[[2, 3], [10, 99], [87, 22]]

请注意,这将删除标记为to_remove的所有元素,而不仅仅是开头的零,我假设这对您没问题,因为您说要删除所有零。