简体   繁体   English

通过在python中出现零来选择列表中的元素

[英]select elements in a list by the occurrence of zeros in python

Given a 2D list: 给出2D列表:

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

I need to get a 2D list that groups all the sublists, separated by zeros in the X[1] column. 我需要获得一个2D列表,该列表将所有子列表分组,在X[1]列中用零分隔。 I mean, I need to select: 我的意思是,我需要选择:

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

ang get a list of the corresponding X[0] entries only: ang只获取相应的X[0]条目列表:

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

I've already asked a similar question for selecting elements within a list, on the basis of the occurrences of zeros inside it, but it was a 1D list. 我已经问了一个类似的问题,根据列表中的零点选择列表中的元素,但它是一维列表。 Using itertools, I tried something like: 使用itertools,我尝试了类似的东西:

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

where I used X[:,1] to act on the X[1] part of the list, as the selection acts on it. 我使用X[:,1]作用于列表的X[1]部分,因为选择作用于它。 But it obviously gives me the X[1] part of the list: 但它显然给了我列表的X[1]部分:

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

But I need the X[0] column... how can I use itertools on multi-dimensional lists? 但我需要X[0]专栏......如何在多维列表上使用itertools? Thanks in advance. 提前致谢。

I believe this will do the work: 我相信这会做的工作:

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

More explanation: 更多解释:

you want to groupby X according to the second value of each item in the list so you need to do: 你想根据列表中每个项目的第二个值对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] will create the 2D list like that: [list(v) for k, v in itertools.groupby(X, lambda x: x[1] == 0) if not k]将创建如下的2D列表:
[[['a', 2], ['b', 12], ['c', 6]], [['e', 2]], [['h', 12], ['i', 18]]] so you need to manipulate each item in the list and take only the second index, this can be done with the map function: [[['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]

You can define your own splitter using an iterator: 您可以使用迭代器定义自己的拆分器:

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']]

If you work with characters, here is an approach - despite I prefer the splitter for your particular problem: 如果你使用角色,这是一种方法 - 尽管我更喜欢你的特定问题的分离器:

[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']]

I would also improve/shorten @Elisha answer with a small hack: 我还会用小黑客改进/缩短@Elisha的答案:

from itertools import groupby

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

I will do it like this: 我会这样做:

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']]

It's just found the "zero" indices and then using slices to get the right lists of lists. 它只是找到了“零”索引,然后使用切片来获得正确的列表列表。

Of course you can remove the empty lists at the end. 当然,您可以在最后删除空列表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM