使用python加入上一句和下一句

时间:2010-06-18 14:57:51

标签: iterator python

我正在尝试加入list中包含的一组句子。我有一个功能,它确定一个句子是否值得保存。但是,为了保持句子的上下文,我还需要在它之前和之后保留句子。在边缘情况下,无论是第一个还是最后一个句子,我只会保留句子及其唯一的邻居。

最好的例子是:

    ex_paragraph = ['The quick brown fox jumps over the fence.', 
                   'Where there is another red fox.', 
                   'They run off together.', 
                   'They live hapily ever after.']
    t1 = lambda x: x.startswith('Where')
    t2 = lambda x: x'startswith('The ')

t1的结果应为:

['The quick brown fox jumps over the fence. Where there is another red fox. They run off together.']

t2的结果应为:

['The quick brown fox jumps over the fence. Where there is another red fox.']

我的解决方案是:

def YieldContext(sent_list, cont_fun):
    def JoinSent(sent_list, ind):
        if ind == 0:
            return sent_list[ind]+sent_list[ind+1]
        elif ind == len(sent_list)-1:
            return sent_list[ind-1]+sent_list[ind]
        else:

            return ' '.join(sent_list[ind-1:ind+1])


    for sent, sentnum in izip(sent_list, count(0)):
        if cont_fun(sent):
            yield JoinSent(sent_list, sent_num)

有没有人知道这样做的“更清洁”或更多的pythonic方法。 if-elif-else似乎有点被迫。

谢谢,

威尔

PS。我显然是用更复杂的“上下文函数”来做这件事,但这只是一个简单的例子。

4 个答案:

答案 0 :(得分:4)

在列表的开头和结尾添加一个空字符串实际上是一个好主意,但实际上并不需要使用花式列表理解等。您可以非常轻松地构建生成器:

def yieldContext(l, func):
    l = [''] + l + ['']
    for i, s in enumerate(l):
        if func(s):
            yield ' '.join(l[i-1:i+2]).strip()

给出:

>>> print list(yieldContext(ex_paragraph, t1))
['The quick brown fox jumps over the fence. Where there is another red fox. They run off together.']

>>> print list(yieldContext(ex_paragraph, t2))
['The quick brown fox jumps over the fence. Where there is another red fox.']

(如果你真的想创建一个列表,那就没什么区别了。这主要取决于你有多少句话以及你想用“上下文”做什么) < / p>

def yieldContext(l, func):
    l = [''] + l + ['']
    return [' '.join(l[i-1:i+2]).strip() for i, s in enumerate(l) if func(s)]

答案 1 :(得分:1)

我可能会这样做:

from itertools import izip, tee
prev, this, next = tee([''] + ex_paragraph + [''], 3)
this.next()
next.next()
next.next()
[' '.join(ctx).strip() for ctx in izip(prev, this, next) if cont_fun(this)]

其中cont_funt1t2之一。

答案 2 :(得分:1)

好吧,我可能只在oneline上写iffs:

def join_send(sent_list, ind):
    items = [sent_list[i] for i in (ind-1, ind, ind+1) if i >= 0 and i < len(sent_list)]
    return ' '.join(items)

但如果这是可读的,那可能是有争议的。

P.S。:使用PEP 8风格的名称,即yield_context,更确切地说是pythonic。或者嘿,即使yieldContext在某些库中也是可行的......但是YieldContext?

答案 3 :(得分:0)

return ' '.join(sent_list[max(0,ind-1):min(len(ind),ind+2)])