select python 中由零分隔的子数组

select subarrays delimited by zeros in python

给出如下列表:

A = [18, 7, 0, 0, 0, 9, 12, 0, 0, 11, 2, 3, 3, 0, 0, 7, 8]

是否有一种简单的方法来创建子数组,这些子数组由零分隔(或至少由 NaN 分隔)?我的意思是,比如:

A1 = [18, 7]
A2 = [9, 12]
A3 = [11, 2, 3, 3]
A4 = [7, 8]

我写过:

q=0
for i in range(0,len(A)):
    if A[i]-A[i-1] < 1:
        q=q+1

检索列表中存在的零数据包数。但是我需要填充子数组,只要我通过列表遇到它们......也许是 split 函数?提前谢谢你。

试试这个:

import itertools as it
A = [18, 7, 0, 0, 0, 9, 12, 0, 0, 11, 2, 3, 3, 0, 0, 7, 8]

[list(v) for k, v in it.groupby(A, lambda x: not x) if not k]
=> [[18, 7], [9, 12], [11, 2, 3, 3], [7, 8]]

嗯,itertools 有适合您的解决方案:groupby(list, filter)

如果要按零分组,请从以下操作开始:

B = itertools.groupby(A, lambda x:x == 0)

lambda 表达式"decides"哪些值应该是分隔符。您可以使用 lambda x: x == None 分隔 Nones(例如)。这将 return 你一个可迭代的对象。因此,使用列表理解,让我们遍历它(每次迭代都会给我们一个 2 值元组):

C = [(i, list(j)) for i, j in B] # j is cast to a list because it's originally an object, not a list.

输出将类似于:

[(False, [18, 7]), (True, [0]), (True, [0]), (True, [0]), ... ]

现在,作为分隔符的每个列表 j 都有一个 i 值 True。所以我们可以过滤它:

C = [list(j) for i, j in B if not i]

现在,结果是一个二维列表:

[[18, 7], [9, 12], [11, 2, 3, 3], [7, 8]]

所以一个线性函数:

def splitArr():
    return [list(j) for i, j in itertools.groupby(A, lambda x:x == 0) if not i]

天真的解决方案:

A = [18, 7, 0, 0, 0, 9, 12, 0, 0, 11, 2, 3, 3, 0, 0, 7, 8]
b = []
c = []
for i in A:
    if i == 0:
        if len(c):
            b.append(c)
        c = []
        continue
    c.append(i)
if len(c):
    b.append(c)