假设您有一个任意元素列表,如
['monkey', 'deer', 'lion', 'giraffe', 'lion', 'eagle', 'lion', 'fish']
应该在给定谓词的每个元素之后分成子列表,例如,
is_lion(element)
返回True
。上面的例子应该成为
[['monkey', 'deer', 'lion'], ['giraffe', 'lion'], ['eagle', 'lion'], ['fish']]
有没有pythonic方式吗?
答案 0 :(得分:5)
最简单的方法可能是:
out = [[]]
for element in lst:
out[-1].append(element)
if predicate(element):
out.append([])
请注意,这会在最后out
的{{1}},if predicate(element):
末尾留下一个空列表。您可以通过添加以下内容来删除它:
element
答案 1 :(得分:2)
仅仅因为我们可以,一个功能性的单行:
from functools import reduce
reduce(lambda out, x: out[:-1] + [out[-1] + [x]] if not predicate(x) else out + [[x]], x, [[]])
答案 2 :(得分:1)
我更喜欢这个解决方案:
def f(outs, x):
if outs[-1][-1:] == ["lion"]:
outs.append([])
outs[-1].append(x)
return outs
def splitAfterLion(xs):
return reduce(f,xs,[[]])
它可能不是非常pythonic,更实用。但它很简短,并且不会因结果中的空列表而受到影响。
答案 3 :(得分:0)
>>> import itertools
>>> l = ['monkey', 'deer', 'lion', 'giraffe', 'lion', 'eagle', 'lion', 'fish']
>>> f = lambda i: i == "lion"
>>> a = [list(j) for i, j in itertools.groupby(l, f)]
>>> a
[['monkey', 'deer'], ['lion'], ['giraffe'], ['lion'], ['eagle'], ['lion'], ['fish']]
>>> [i+j for i, j in zip(a[::2], a[1::2])]
[['monkey', 'deer', 'lion'], ['giraffe', 'lion'], ['eagle', 'lion']]
编辑:
>>> [i+j for i, j in itertools.zip_longest(a[::2], a[1::2], fillvalue=[])]
[['monkey', 'deer', 'lion'], ['giraffe', 'lion'], ['eagle', 'lion'], ['fish']]
答案 4 :(得分:0)
通过不使用itertool获取索引的另一种方法,请告诉我这是否适合您:
#!/usr/bin/python
ls = ['monkey', 'deer', 'lion', 'giraffe', 'lion', 'eagle', 'lion', 'fish', 'fish']
def is_lion(elm):
return elm in ls
def mark_it(nm):
ind = [ x+1 for x,y in enumerate(ls) if y == nm ]
if ind[-1] < len(ls):
ind.append(len(ls))
return ind
def merge_it(ind):
return [list(ls[x[0]:x[1]]) for x in zip(ind[::], ind[1::])]
name = 'lion'
if is_lion(name):
index = [0]
index.extend(mark_it(name))
print merge_it(index)
else:
print 'not found'
输出:
[['monkey', 'deer', 'lion'], ['giraffe', 'lion'], ['eagle', 'lion'], ['fish', 'fish']]
答案 5 :(得分:0)
这是一个解决方案:
def is_lion(a, element):
start = 0
for key,value in enumerate(a):
if value == element:
yield a[start:key+1]
start = key+1
# print out the last sub-list
if value != 'lion':
yield a[start:key+1]
a = ['monkey', 'deer', 'lion', 'giraffe', 'lion', 'eagle', 'lion', 'fish']
print [x for x in is_lion(a, 'lion')]