3

我有四个大小相同的 NumElements 数组,例如 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 长。我知道我应该使用数组副本,但是数组很长,我想保持低内存消耗,因为我在 Java 虚拟机中工作(不要问:(((())。另外,我想要一种高效的方法,但最重要的是可读(这段代码必须由像我这样的 Python 文盲维护,所以我需要 KISS)。

4

6 回答 6

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)
于 2013-07-19T10:20:13.160 回答
4

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

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

通过反向循环列表,您可以保持索引稳定(仅删除当前索引之后的元素,仅缩小列表的尾部)。由于您没有使用list.pop()(无论如何,您得到的都是0s,对吗?)的返回值,您也可以只del在列表索引上使用。

reversed(range(NumElements))这里用的不是计算更费劲range(NumElements - 1, -1, -1);它同样有效,但更具可读性。该reversed()函数返回一个迭代器,非常有效地处理反转的数列。在 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])
于 2013-07-19T10:20:04.690 回答
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)
于 2013-07-19T10:14:47.973 回答
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]   
于 2013-07-19T10:13:09.967 回答
1

查看我在 Python 中访问的其他答案列表。您可以遍历列表A并将 0 的索引存储在临时列表中,然后弹出它们。

于 2013-07-19T10:17:45.930 回答
1

这可能是一个 hack,但它很简单并且有效

>>> 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 的元素,而不仅仅是开头的零,我假设这对您来说没问题,因为您说您要删除所有零。

于 2013-07-19T10:23:58.323 回答