2016-07-01 2 views
1

itertools 파이썬 모듈은 반복자에 대한 몇 가지 기본 구성 요소를 구현합니다. 그들이 말했듯이 "iterator algebra"를 형성합니다. 예상 했었지만 모듈을 사용하여 다음 반복을 수행하는 간결한 방법을 찾을 수 없었습니다. 예를 들어, 주문 실수의 목록을 감안할 때 리스트의 n 연속 요소 반복 (겹침)

a = [1.0,1.5,2.0,2.5,3.0] 
는 ... 일부 n 값으로 그룹화 새로운 목록을 반환 (또는 반복), 2

b = [(1.0,1.5),(1.5,2.0),(2.0,2.5),(2.5,3.0)] 

내가 일을 발견하는 방법을 말한다 이것은 다음과 같았다. 먼저 고르게 및 확률 인덱스, 두 목록을 분할 :

b = [(even, odd) for even, odd in zip(evens, odds)] 
b = sorted(b + [(odd, even) for even, odd in zip(evens[1:], odds)]) 

본질적으로, 그것은 이동 평균에게 유사합니다

even, odds = a[::2], a[1::2] 

그런 다음 새 목록을 구성.

itertools가 있든 없든 간결하게이 방법이 있습니까? 이 코드가되고있는

timestamp  event 
47.8   1a 
60.5   1b 
67.4   2a 
74.5   2b 
78.5   1a 
82.2   1b 
89.5   2a 
95.3   2b 
101.7   1a 
110.2   1b 
121.9   2a 
127.1   2b 

... 

: PS :

응용 프로그램

이 일부 이벤트의 타임 스탬프 세트로 a 목록을 상상해


는 실험 기간 동안 발생 다른 시간 창과 일치하는 이벤트를 구분하는 데 사용됩니다. 지금은 2 연속 이벤트 사이의 데이터에 관심이 있습니다. 'n> 2'는 탐색 목적으로 만 사용됩니다.

답변

3

2의 경우, 당신은 단지 고정 N 들어

b = zip(a, a[1:]) # or list(zip(...)) on Python 3 if you really want a list 

을 수행 할 수 있습니다,이 기술은 비슷하다

, 변수 (n)에 대한
# n = 4 
b = zip(a, a[1:], a[2:], a[3:]) 

, 당신은 특히 (조각의 변수 수를 압축, 또는 수 창 크기가 a 크기에 가까우면 창을 직접 찍기 위해 슬라이싱을 사용할 수 있습니다.

b = zip(*[a[i:] for i in xrange(n)]) 
# or 
b = [tuple(a[i:i+n]) for i in xrange(len(a)-n)] 

a이 목록에없는 경우, 당신은 itertools 워드 프로세서에서 pairwise 조리법을 일반화 수 :

import copy 
import itertools 

def nwise(iterable, n): 
    # Make n tees at successive positions along the iterable. 
    tees = list(itertools.tee(iterable, 1)) 
    for _ in xrange(n-1): 
     tees.append(copy.copy(tees[-1])) 
     next(tees[-1]) 

    return zip(*tees) 
+0

@glibdud : 아, 네 말이 맞아. 단일 티는 여전히 단일 요소 튜플에 래핑됩니다. – user2357112

4

이것은 pairwise itertools recipe가 무엇인지 정확하게, n=2을 위해입니다.

from itertools import tee 

def pairwise(iterable): 
    "s -> (s0,s1), (s1,s2), (s2, s3), ..." 
    a, b = tee(iterable) 
    next(b, None) 
    return zip(a, b) 

데모 :

>>> b = [1.0,1.5,2.0,2.5,3.0] 
>>> list(pairwise(b)) 
[(1.0, 1.5), (1.5, 2.0), (2.0, 2.5), (2.5, 3.0)] 

당신이 변수 그룹 크기를 찾는 경우에, (나는 접근 방식을 좋아한다) user2357112's answer를 참조, 또는 더 일반적으로는 슬라이딩 윈도우 반복자를 구현할 수 및 걸릴 조각 of which there are many approaches . 여담으로


, 가능성이 가난 새로운 yield from 구문을 사용하여, 즉이 될 것입니다 링크 된 질문에없는 수행하지만 재미있는 한 줄의 창은 (중복을 제어 할 수 )를 슬라이스 할 수 결합 발전기.

from itertools import tee, islice 
def roll_window(it, sz): 
    yield from zip(*[islice(it, g, None) for g, it in enumerate(tee(it, sz))]) 

데모 :

>>> b = [1.0,1.5,2.0,2.5,3.0, 3.5, 4.0, 4.5] 
>>> list(islice(window(b, 3), None, None, 2)) 
[(1.0, 1.5, 2.0), (2.0, 2.5, 3.0), (3.0, 3.5, 4.0)] 
1

발전기를 사용 :

def groupListByN(lst, n): 
    for i in range(len(a)-n+1): 
    yield lst[i:i+n] 

a = [1.0,1.5,2.0,2.5,3.0] 
myDoubleList = [group for group in groupListByN(a, 2)] 
myTripleList = [group for group in groupListByN(a, 3)] 

print(myDoubleList) 
print(myTripleList) 

결과 :

[[1.0, 1.5], [1.5, 2.0], [2.0, 2.5], [2.5, 3.0]] 
[[1.0, 1.5, 2.0], [1.5, 2.0, 2.5], [2.0, 2.5, 3.0]] 

나는이 솔루션은 매우 간결 생각