source

목록의 모든 연속된 항목 쌍에 대해 반복

nicesource 2023. 8. 7. 22:36
반응형

목록의 모든 연속된 항목 쌍에 대해 반복

목록 지정

l = [1, 7, 3, 5]

모든 연속 목록 항목 쌍에 대해 반복하려고 합니다.(1,7), (7,3), (3,5),예.

for i in xrange(len(l) - 1):
    x = l[i]
    y = l[i + 1]
    # do something

좀 더 콤팩트한 방식으로 하고 싶습니다.

for x, y in someiterator(l): ...

내장된 파이썬 중계기를 사용하여 이를 수행할 수 있는 방법이 있습니까?틀림없이itertools모듈에 해결책이 있어야 하는데, 도저히 이해할 수가 없습니다.

그냥 zip을 사용하세요.

>>> l = [1, 7, 3, 5]
>>> for first, second in zip(l, l[1:]):
...     print(first, second)
...
1 7
7 3
3 5

Python 2(권장되지 않음)를 사용하는 경우에는izip에서 기능하는.itertools새 목록을 만들지 않을 매우 긴 목록의 경우.

import itertools

for first, second in itertools.izip(l, l[1:]):
    ...

보다pairwiseatiter tools 레시피: http://docs.python.org/2/library/itertools.html#recipes

거기서 인용한 내용:

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

일반 버전

주어진 양의 자연 크기의 튜플을 생성하는 일반 버전은 다음과 같이 보일 수 있습니다.

def nwise(iterable, n=2):                                                      
    iters = tee(iterable, n)                                                     
    for i, it in enumerate(iters):                                               
        next(islice(it, i, i), None)                                               
    return izip(*iters)   

제네릭을 생성합니다.grouper발전기, 이렇게

def grouper(input_list, n = 2):
    for i in xrange(len(input_list) - (n - 1)):
        yield input_list[i:i+n]

표본 런 1

for first, second in grouper([1, 7, 3, 5, 6, 8], 2):
    print first, second

산출량

1 7
7 3
3 5
5 6
6 8

표본 런 1

for first, second, third in grouper([1, 7, 3, 5, 6, 8], 3):
    print first, second, third

산출량

1 7 3
7 3 5
3 5 6
5 6 8

이해력을 통해 nwise에 대한 sberry의 접근 방식 일반화:

def nwise(lst, k=2):
    return list(zip(*[lst[i:] for i in range(k)])) 

에그

nwise(list(range(10)),3)

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

불필요한 복사 없이 이를 수행할 수 있는 간단한 방법은 이전 요소를 저장하는 생성기입니다.

def pairs(iterable):
    """Yield elements pairwise from iterable as (i0, i1), (i1, i2), ..."""
    it = iter(iterable)
    try:
        prev = next(it)
    except StopIteration:
        return
    for item in it:
        yield prev, item
        prev = item

인덱스 기반 솔루션과 달리 인덱싱이 지원되지 않거나 느린 솔루션(예: 제너레이터)을 포함하여 모든 반복 가능한 솔루션에서 작동합니다.collections.deque).

사용할 수 있습니다.zip.

>>> list(zip(range(5), range(2, 6)))
[(0, 1), (1, 2), (2, 3), (3, 4), (4, 5)]

마치 지퍼처럼, 그것은 짝을 만듭니다.따라서 두 목록을 혼합하면 다음과 같은 이점을 얻을 수 있습니다.

>>> l = [1,7,3,5]
>>> list(zip(l[:-1], l[1:]))
[(1, 7), (7, 3), (3, 5)]

그 다음에 반복하면 다음과 같습니다.

for x, y in zip(l[:-1], l[1:]):
    pass

인라인 방식을 원했지만 제대로 읽을 수 없는 경우 발전기를 사용하는 또 다른 솔루션이 있습니다.역시 최고의 성능은 아닌 것 같습니다 :-/

목록을 마지막 항목 앞에 종료할 조정이 있는 생성기로 변환:

gen = (x for x in l[:-1])

쌍으로 변환:

[(gen.next(), x) for x in l[1:]]

그게 당신이 필요한 전부입니다.

언급URL : https://stackoverflow.com/questions/21303224/iterate-over-all-pairs-of-consecutive-items-in-a-list

반응형