2017-04-19 1 views
0

하나의 인덱스로만 "이동"하는 목록에서 연속적인 항목을 반환 할 수있는 생성기를 만들려고합니다. DSP의 이동 평균 필터와 비슷한 점. 나는이 출력 기대아이템 그룹을 반환하는 파이썬 생성기

l = [1,2,3,4,5,6,7,8,9] 

: 예를 들어 나는 목록이있는 경우 내가 코드를 만든

[(1,2,3),(2,3,4),(3,4,5),(4,5,6),(5,6,7),(6,7,8),(7,8,9)] 

을하지만 등 나는 그것이 인해 중단됩니다 두려워 필터와 발전기가 작동하지 않습니다 큰 목록의 단어를 제공해야하는 경우 메모리에 저장하십시오.

기능 gen :

def gen(enumobj, n): 
    for idx,val in enumerate(enumobj): 
     try: 
      yield tuple(enumobj[i] for i in range(idx, idx + n)) 
     except: 
      break 

및 예제 코드 :

words = ['aaa','bb','c','dddddd','eeee','ff','g','h','iiiii','jjj','kk','lll','m','m','ooo'] 
w = filter(lambda x: len(x) > 1, words) 

# It's working with list 
print('\nList:') 
g = gen(words, 4) 
for i in g: print(i) 

# It's not working with filetrs/generators etc. 
print('\nFilter:') 
g = gen(w, 4) 
for i in g: print(i) 

아무것도 생성하지 않습니다에 대한 목록입니다. 필터 객체를 인덱싱 할 수 없으므로 코드가 중단됩니다. 물론 대답 중 하나는리스트를 강요하는 것입니다 : list(w). 그러나, 나는 더 나은 코드 기능을 찾고있다. 함수가 필터 등을 받아 들일 수 있도록 어떻게 변경할 수 있습니까? 목록의 엄청난 수의 데이터에 대해 메모리가 걱정됩니다.

감사 이미 읽은 값을 추적 할 필요가 반복자와

답변

1

. n 크기 목록은 트릭을 수행합니다. 목록에 다음 값을 추가하고 각 항복 후에 최상위 항목을 버립니다.

import itertools 

def gen(enumobj, n): 
    # we need an iterator for the `next` call below. this creates 
    # an iterator from an iterable such as a list, but leaves 
    # iterators alone. 
    enumobj = iter(enumobj) 
    # cache the first n objects (fewer if iterator is exhausted) 
    cache = list(itertools.islice(enumobj, n)) 
    # while we still have something in the cache... 
    while cache: 
     yield cache 
     # drop stale item 
     cache.pop(0) 
     # try to get one new item, stopping when iterator is done 
     try: 
      cache.append(next(enumobj)) 
     except StopIteration: 
      # pass to emit progressively smaller units 
      #pass 
      # break to stop when fewer than `n` items remain 
      break 

words = ['aaa','bb','c','dddddd','eeee','ff','g','h','iiiii','jjj','kk','lll','m','m','ooo'] 
w = filter(lambda x: len(x) > 1, words) 

# It's working with list 
print('\nList:') 
g = gen(words, 4) 
for i in g: print(i) 

# now it works with iterators 
print('\nFilter:') 
g = gen(w, 4) 
for i in g: print(i) 
+0

안녕하세요. 나는 두 가지 것에 대해 물어볼 필요가있다. 제 말은 처음 두 줄은 발전기를 초기화하고 발전기가 작동을 시작할 때만 실행된다는 것입니다. iterable은 객체를 처음으로 슬라이스 할 필요가있는 것처럼 보입니다. 어떤 종류의 조건이'while data :'행에서 검사되고 왜'data'입니까? 나에게 함수는 'yield data'를 통해 값을 반환하고, 그 값이 일시 정지되면 코드는 다시 다음 줄로 돌아 간다. 그 맞습니까? 미안 나는 발전기를 만드는 새로운 있습니다. 감사합니다. – Celdor

+0

나는'pass'를'break'로 변경했습니다. 그렇지 않으면 함수는 길이가 n-1, n-2, .., 1 인 추가 항목을 반환합니다. – Celdor

+0

반복기에 시작하는 항목이 n 개 미만인 경우 문제가 될 수 있습니다. 'islice' 바로 다음에 체크를 추가하고 즉시 리턴 할 수 있습니다. – tdelaney