2010-06-18 2 views
1

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) 

누구나 이와 같은 작업을하는 "더 깨끗한"방법이나 더 평범한 방법을 알고 있습니까? if-elif-else은 약간 강제 된 것처럼 보입니다.

감사합니다,

PS. 분명히 더 복잡한 "문맥 함수"를 사용하여 이것을 수행하고 있습니다. 그러나 이것은 간단한 예제 일뿐입니다.

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_funt1 또는 t2 중 하나입니다

답변

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

(당신이 정말로 목록을 만들려면 큰 차이가없는 그것은 주로에 따라 달라집니다. 얼마나 많은 문장 당신은 무엇을 당신이 "상황"에 대해 수행 할)

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

내가 생각 하기엔, 비록 내가 Judo라는 인상을 받았지만, 발전기를 사용하여리스트를 만들려고했다. ... –

+0

@David Zaslavsky : 글쎄, 그것은 그가 가지고있는 데이터에 달려있다. 그리고 어쨌든 차이가별로 없습니다 ... –

+0

멋지고 읽을 수있는 ... 정확히 내가 무엇을 찾고 있었습니까! – JudoWill

1

나는 같은 것을 할 수 있습니다.

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) 

을하지만이 가능한 경우는 아마 논란의 :

+0

멋지다. itertools 기반 솔루션이 있는지 궁금하다. 내 단락이 매우 길면 좋을 것입니다. 파일에서 게으른로드입니다. – JudoWill

1

글쎄, 난 아마 단지 oneline에 iffs을 쓸 것입니다.

P .: 더 확실한 것은 PEP 8 스타일 이름 즉, yield_context를 사용하는 것입니다. 아니면 이봐, yieldContext조차도 일부 라이브러리에서 가능할 것이다 ...하지만 YieldContext?

+0

와우, 그건 꽤 인상적인리스트 - 이해력입니다. 지금은 이해할 수 있지만, 리팩토링해야한다면 3 개월 내에 이해할 수 있을지 확실하지 않습니다. – JudoWill

+0

의존 - 나는 그것들을 읽을 수 있고 실제로 많은 functools/itertools 것들을 좋아한다는 것을 알았지 만, 나는 추한 것처럼 보일 수도 있고 많은 사람들이 읽을 수있는 것이 아니라고 완전히 인정한다. – Almad

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