在给定谓词为true的元素之后拆分列表的Pythonic方法

在给定谓词为true的元素之后拆分列表的Pythonic方法,python,list,Python,List,假设您有一个任意元素的列表,如 [‘猴子’、‘鹿’、‘狮子’、‘长颈鹿’、‘狮子’、‘鹰’、‘狮子’、‘鱼’] 应该在每个元素之后将其拆分为子列表,每个元素对应一个给定的谓词,例如 is\u lion(元素) 返回True。上面的例子应该是 有一种类似蟒蛇的方法吗?最简单的方法可能是: out = [[]] for element in lst: out[-1].append(element) if predicate(element): out.append(

假设您有一个任意元素的列表,如

[‘猴子’、‘鹿’、‘狮子’、‘长颈鹿’、‘狮子’、‘鹰’、‘狮子’、‘鱼’]

应该在每个元素之后将其拆分为子列表,每个元素对应一个给定的谓词,例如

is\u lion(元素)

返回
True
。上面的例子应该是


有一种类似蟒蛇的方法吗?

最简单的方法可能是:

out = [[]]
for element in lst:
    out[-1].append(element)
    if predicate(element):
        out.append([])
请注意,这将在
out
的末尾留下一个空列表,
如果谓词(元素):
为最后一个
元素
。您可以通过添加以下内容来删除此项:

out = [l for l in out if l]
编辑:


另一种方法是不使用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'
以下是一个解决方案:

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')]
def f(outs, x):
    if outs[-1][-1:] == ["lion"]:
        outs.append([])
    outs[-1].append(x)
    return outs

def splitAfterLion(xs):
    return reduce(f,xs,[[]])

仅仅因为我们可以,一个功能性的单行程序:

from functools import reduce

reduce(lambda out, x: out[:-1] + [out[-1] + [x]] if not predicate(x) else out + [[x]], x, [[]])

我比较喜欢这个解决方案:

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')]
def f(outs, x):
    if outs[-1][-1:] == ["lion"]:
        outs.append([])
    outs[-1].append(x)
    return outs

def splitAfterLion(xs):
    return reduce(f,xs,[[]])

它可能不是很像蟒蛇,更具功能性。但它很短,并且不会在结果中出现拖尾空列表。

@Aश威尼च没错,我错过了这个。然而,我认为这样问的问题更一般。@Aश威尼च豪德利,你发布的问题与这个问题非常接近。不完全是,但这足以让我感到不舒服。连续的
狮子应该如何处理?@jornsharpe
['snake','lion','lion']
返回
['snake','lion'],['lion']]
您删除了
…感谢您的注意,已修复。此外,这将连续的
狮子
分组到一个列表中
def f(outs, x):
    if outs[-1][-1:] == ["lion"]:
        outs.append([])
    outs[-1].append(x)
    return outs

def splitAfterLion(xs):
    return reduce(f,xs,[[]])