select 列表中的元素在 python 中出现零

select elements in a list by the occurrence of zeros in python

给定一个二维列表:

X = [ [a,2], [b,12], [c,6], [d,0], [e,2], [f,0], [g,0], [h,12], [i,18] ]

我需要一个二维列表,将所有子列表分组,在 X[1] 列中用零分隔。我的意思是,我需要 select:

Y = [ [[a,2],[b,12],[c,6]], [[e,2]], [[h,12],[i,18]] ]

仅获取相应 X[0] 条目的列表:

Y = [ [a, b, c], [e], [h, i] ]

我已经针对列表中的 selecting 元素提出了类似的问题,基于其中出现的零,但它是一维列表。使用 itertools,我尝试了类似的东西:

Z = [list(v) for k, v in itertools.groupby(X[:,1], lambda x: x == 0) if not k] 

我使用 X[:,1] 作用于列表的 X[1] 部分,因为 selection 作用于它。但它显然给了我列表的 X[1] 部分:

Z = [[2, 12, 6], [2], [12, 18]]

但我需要 X[0] 列...如何在多维列表上使用 itertools?提前致谢。

我相信这会起作用:

[map(lambda a:a[0],list(v)) for k, v in itertools.groupby(X, lambda x: x[1] == 0) if not k]

更多解释:

你想根据列表中每一项的第二个值对X进行分组,所以你需要做:
itertools.groupby(X, lambda x: x[1] == 0)

[list(v) for k, v in itertools.groupby(X, lambda x: x[1] == 0) if not k] 将创建这样的二维列表:
[[['a', 2], ['b', 12], ['c', 6]], [['e', 2]], [['h', 12], ['i', 18]]] 所以你需要操作列表中的每个项目并只取第二个索引,这可以用 map 函数来完成:

[map(lambda a:a[0],list(v)) for k, v in itertools.groupby(X, lambda x: x[1] == 0) if not k]

我会这样做:

X = [ ['a',2], ['b',12], ['c',6], ['d',0], ['e',2], ['f',0], ['g',0], ['h',12], ['i',18] ]
ind = [-1] + [i for i in range(n) if X[i][1]==0] + [len(X)] # found the indices of the "zero" lists
Y = [X[ind[i]+1:ind[i+1]] for i in range(len(ind)-1)] # choose the items between those indices
Y = [[x[0] for x in list] for list in Y] # take only X[0]
Y
#output
[['a', 'b', 'c'], ['e'], [], ['h', 'i']]

刚刚找到 "zero" 个索引,然后使用切片获取正确的列表列表。

当然你可以去掉最后的空列表。

您可以使用迭代器定义自己的拆分器:

def splitter(L):
    group = []
    res = []
    for i in iter(L):
        if i[1]:
            group.append(i[0])
        if not i[1] and len(group):
            res.append(group)
            group = []
    if len(group):
        res.append(group)
    return res

#In [62]: splitter(X)
#Out[62]: [['a', 'b', 'c'], ['e'], ['h', 'i']]

如果您使用字符,这里有一个方法 - 尽管我更喜欢拆分器来解决您的特定问题:

[list(u) for u in ''.join([i[0] if i[1] else '|' for i in X]).split("|") if u]
#[['a', 'b', 'c'], ['e'], ['h', 'i']]

我也会 improve/shorten @Elisha 用一个小技巧回答:

from itertools import groupby

[list(zip(*v)[0]) for k, v in groupby(X, lambda x: x[1] == 0) if not k]