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]
给定一个二维列表:
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]