[python] 목록의 두 요소마다 반복

어떻게 내가 어떻게해야합니까 for루프 또는 모든 반복이 나에게 두 가지 요소를 제공하도록 지능형리스트를?

l = [1,2,3,4,5,6]

for i,k in ???:
    print str(i), '+', str(k), '=', str(i+k)

산출:

1+2=3
3+4=7
5+6=11



답변

pairwise()(또는 grouped()) 구현 이 필요합니다 .

파이썬 2의 경우 :

from itertools import izip

def pairwise(iterable):
    "s -> (s0, s1), (s2, s3), (s4, s5), ..."
    a = iter(iterable)
    return izip(a, a)

for x, y in pairwise(l):
   print "%d + %d = %d" % (x, y, x + y)

또는 더 일반적으로 :

from itertools import izip

def grouped(iterable, n):
    "s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), (s2n,s2n+1,s2n+2,...s3n-1), ..."
    return izip(*[iter(iterable)]*n)

for x, y in grouped(l, 2):
   print "%d + %d = %d" % (x, y, x + y)

Python 3에서는 izip내장 zip()함수로 대체하고을 삭제할 수 import있습니다.

내 질문에 대한 그의 답변 에 대한 마 티노에 대한 모든 신용 은 목록을 한 번만 반복하고 프로세스에서 불필요한 목록을 만들지 않기 때문에 이것이 매우 효율적이라는 것을 알았습니다.

NB는 :이은과 혼동해서는 안 pairwise조리법 파이썬의 자신의 itertools문서 , 수율 s -> (s0, s1), (s1, s2), (s2, s3), ...에 의해 지적 밖으로로서, @lazyr 의견이다.

Python 3 에서 mypy로 유형 검사를하고 싶은 사람들에게는 거의 추가되지 않습니다 .

from typing import Iterable, Tuple, TypeVar

T = TypeVar("T")

def grouped(iterable: Iterable[T], n=2) -> Iterable[Tuple[T, ...]]:
    """s -> (s0,s1,s2,...sn-1), (sn,sn+1,sn+2,...s2n-1), ..."""
    return zip(*[iter(iterable)] * n)


답변

두 요소의 튜플이 필요합니다.

data = [1,2,3,4,5,6]
for i,k in zip(data[0::2], data[1::2]):
    print str(i), '+', str(k), '=', str(i+k)

어디:

  • data[0::2] 요소의 하위 집합 모음을 만드는 것을 의미합니다. (index % 2 == 0)
  • zip(x,y) x 및 y 컬렉션에서 동일한 인덱스 요소로 튜플 컬렉션을 만듭니다.

답변

>>> l = [1,2,3,4,5,6]

>>> zip(l,l[1:])
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]

>>> zip(l,l[1:])[::2]
[(1, 2), (3, 4), (5, 6)]

>>> [a+b for a,b in zip(l,l[1:])[::2]]
[3, 7, 11]

>>> ["%d + %d = %d" % (a,b,a+b) for a,b in zip(l,l[1:])[::2]]
['1 + 2 = 3', '3 + 4 = 7', '5 + 6 = 11']


답변

간단한 해결책.

l = [1, 2, 3, 4, 5, 6]

범위 (i, len (l), 2)의 i의 경우 :
    str (l [i]), '+', str (l [i + 1]), '=', str (l [i] + l [i + 1]) 인쇄


답변

사용하는 모든 답변 zip이 정확 하지만 기능을 직접 구현하면 더 읽기 쉬운 코드로 연결됩니다.

def pairwise(it):
    it = iter(it)
    while True:
        try:
            yield next(it), next(it)
        except StopIteration:
            # no more elements in the iterator
            return

it = iter(it)부분은 it반복 가능한 것이 아니라 실제로 반복자 임을 보장합니다 . 경우 it이미이 반복자이며,이 라인은 no-op입니다.

용법:

for a, b in pairwise([0, 1, 2, 3, 4, 5]):
    print(a + b)


답변

나는 이것이 더 우아한 방법이되기를 바랍니다.

a = [1,2,3,4,5,6]
zip(a[::2], a[1::2])

[(1, 2), (3, 4), (5, 6)]


답변

성능에 관심이있는 경우 simple_benchmark솔루션의 성능을 비교하기 위해 작은 벤치 마크 (내 라이브러리 사용 )를 수행했으며 패키지 중 하나의 기능을 포함했습니다.iteration_utilities.grouper

from iteration_utilities import grouper
import matplotlib as mpl
from simple_benchmark import BenchmarkBuilder

bench = BenchmarkBuilder()

@bench.add_function()
def Johnsyweb(l):
    def pairwise(iterable):
        "s -> (s0, s1), (s2, s3), (s4, s5), ..."
        a = iter(iterable)
        return zip(a, a)

    for x, y in pairwise(l):
        pass

@bench.add_function()
def Margus(data):
    for i, k in zip(data[0::2], data[1::2]):
        pass

@bench.add_function()
def pyanon(l):
    list(zip(l,l[1:]))[::2]

@bench.add_function()
def taskinoor(l):
    for i in range(0, len(l), 2):
        l[i], l[i+1]

@bench.add_function()
def mic_e(it):
    def pairwise(it):
        it = iter(it)
        while True:
            try:
                yield next(it), next(it)
            except StopIteration:
                return

    for a, b in pairwise(it):
        pass

@bench.add_function()
def MSeifert(it):
    for item1, item2 in grouper(it, 2):
        pass

bench.use_random_lists_as_arguments(sizes=[2**i for i in range(1, 20)])
benchmark_result = bench.run()
mpl.rcParams['figure.figsize'] = (8, 10)
benchmark_result.plot_both(relative_to=MSeifert)

여기에 이미지 설명을 입력하십시오

따라서 외부 의존성이없는 가장 빠른 솔루션을 원한다면 Johnysweb이 제공 한 접근 방식을 사용해야합니다 (작성 시점에서 가장 찬성되고 인정 된 답변입니다).

추가 종속성을 신경 쓰지 않으면 grouperfrom iteration_utilities이 약간 빠를 것입니다.

추가 생각

일부 접근 방식에는 여기에서 설명하지 않은 제한 사항이 있습니다.

예를 들어, 일부 솔루션은 시퀀스 (즉, 목록, 문자열 등)에만 작동합니다. 예를 들어 Margus / pyanon / taskinoor 솔루션은 인덱싱을 사용하고 다른 솔루션은 Johnysweb /과 같은 반복 가능 (시퀀스 생성기, 반복기)에서 작동합니다. mic_e / my 솔루션.

그런 다음 Johnysweb은 2 이외의 다른 크기에서도 작동하는 솔루션을 제공했지만 다른 답변은 그렇지 않습니다 ( iteration_utilities.grouper요소 수를 “그룹”으로 설정할 수도 있음).

그런 다음 목록에 홀수 개의 요소가있는 경우 어떻게해야하는지에 대한 질문도 있습니다. 나머지 품목을 기각해야합니까? 크기가 일정하도록 목록을 채워야합니까? 나머지 품목을 단일 품목으로 반품해야합니까? 다른 대답은이 요점을 직접 다루지 않지만, 아무것도 간과하지 않은 경우 나머지 항목을 무시 해야하는 접근법을 따르지 않습니다 (실무자가 답변을 제외하고 실제로 예외가 발생 함).

으로 grouper당신은 당신이 원하는 무엇을 결정할 수 있습니다 :

>>> from iteration_utilities import grouper

>>> list(grouper([1, 2, 3], 2))  # as single
[(1, 2), (3,)]

>>> list(grouper([1, 2, 3], 2, truncate=True))  # ignored
[(1, 2)]

>>> list(grouper([1, 2, 3], 2, fillvalue=None))  # padded
[(1, 2), (3, None)]