2013-10-06 1 views
2

파이썬에서 생성기가 있다고 가정 해 봅시다. 처음 10 번의 반복과 마지막 10 번의 반복을 제외하고는 모든 것을 반복하고 싶습니다. itertools.islice는이 슬라이싱 작업의 첫 번째 부분을 지원하지만 두 번째 부분은 지원하지 않습니다. 이 작업을 수행하는 간단한 방법이 있습니까?인덱싱 양식 생성기 끝

답변

1

단순한 방법이 없을뿐만 아니라 발생 자 (또는 반복 가능)를 허용하려는 경우에는 전혀 방법이 없습니다. 일반적으로 발전기의 끝에서부터 10 개 항목이 언제인지 또는 발전기가 끝났는지 여부를 알 수있는 방법이 없습니다. 생성기는 한 번에 하나의 항목 만 제공하고 "남은 항목 수"에 대해 알려주지 않습니다. 가장 최근의 10 개 항목을 임시 캐시로 유지 한 다음 생성기가 종료 될 때 (또는!) 출력을 생성해야합니다.

"또는 if"에주의하십시오. 발전기는 유한 할 필요는 없다. 무한 생성기의 경우 "마지막"요소와 같은 것이 없습니다.

2

이와 비슷한 작업이 필요할 수 있습니다. 편집 : 댓글 당 deque 사용을 추가했습니다.

from collections import deque 
def generator(): 
    for i in ['ignore'] * 10 + ['yield this'] * 10 + ['ignore'] * 10: 
     yield i 


def func(mygenerator): 
    cache = deque() 
    for i, item in enumerate(mygenerator()): 
     if i < 10: 
      continue 
     cache.appendleft(item) 
     if len(cache) > 10: 
      yield cache.pop() 

for i in func(generator): 
    print i 
+0

비슷한 해결책을 생각하고있었습니다. 속도가 중요하다면, 캐시를 위해'Queue' 객체를 사용해야 할 수도 있습니다. 필자가 이해하는 한, 목록은 처음부터 반복적으로 삽입하기 위해 최적화되지 않았습니다. –

+0

'collections.deque'를 사용하십시오. 이것은 각 끝의 값에 빠르게 액세스 할 수 있도록 설계되었으므로'insert' ('pushleft')와'pop' 호출은 모두 빠릅니다. 그것은'queue.Queue' (스레드 간의 통신용)의 기초가되는 데이터 구조입니다. – Blckknght

+0

'collections.deque'는'popleft' (엘리먼트를 버리기 위해 호출 될 것입니다)를 오버라이드해서 엘리먼트를 생성 할 수 없다는 것은 다소 유감 스럽지만,'maxlen' 파라미터와 함께 사용할 수 있습니다. .. 그럼 당신은'mydeque (islice (iterable, None, 10), 10)'과 같은 것을 가질 것입니다. –