2013-01-12 4 views
15

-ab두 개의 배열을 동시에 반복하는 pythonic 방법은 무엇입니까? 나는 같은 길이의 두 개의 배열을 가지고있는 경우

a = [4,6,2,6,7,3,6,7,2,5]

일반적으로

b = [6,4,6,3,2,7,8,5,3,5]

, 내가 지금처럼 이런 짓을 했을까 말 :

for i in range(len(a)): 
    print a[i] + b[i] 

보다는 뭔가를 이렇게 :

i=0 
for number in a: 
    print number + b[i] 
    i += 1 

나는 사용 된 방법과 일관되기를 선호하기 때문에.

나는 zip을 알고 있지만 결코 사용하지 않습니다. 이것은 zip을 위해 만들어진 것입니까?

for pair in zip(a,b): 
    print pair[0] + pair[1] 

이 작업을 수행 할 수있는 파이썬 방법이 될 것이다?

답변

17

(@Vincenzo PII가 켰을 때) ab이 짧은 목록은 zip를 사용하는 경우 :

for x, y in zip(a, b): 
    print(x + y) 

을 목록 ab가 긴 경우, 메모리 저장 itertools.izip를 사용

import itertools as IT 
for x, y in IT.izip(a, b): 
    print(x + y) 

zip은 튜플 목록을 생성합니다. ab이 큰 경우 부담이 될 수 있습니다 (메모리 단위).

itertools.izip 반복자를 반환합니다. 반복자는 튜플의 전체 목록을 생성하지 않습니다. for-loop에 의해 요청 될 때만 각 항목을 산출합니다. 따라서 메모리를 절약 할 수 있습니다.

짧은 목록의 zip(a,b)을 호출하는 것이 itertools.izip(a,b)을 사용하는 것보다 빠릅니다. 그러나 Python3에서 zip은 기본적으로 반복기를 반환합니다 (즉, Python2에서는 itertools.izip과 같습니다).관심의


다른 변종 :

+1

이 작업을 완료하려면'future_builtins'도 언급 할 것입니다. – georg

+0

그래서 python3의 zip은 itertools.izip과 동일합니까? 또는 목록의 크기에 따라 변경됩니까? – will

+2

@will : 예, Python3의'zip'은 Python2의'itertools.izip'과 같습니다. (목록의 크기에 따라 동작이 바뀌지는 않습니다.) 파이썬 3에서 오래된'zip' 동작을 얻으려면'list (zip (a, b))'를 사용하십시오. – unutbu

7

자신을 언급 한 바와 같이 가능한 솔루션은 zip을 사용하지만 약간 다르게 당신이 질문을 작성하는 방법에 비해 :

for x, y in zip(a, b): 
    print x, y 

공지 사항 zip()에 의해 반환 된 튜플의리스트의 길이가 동일 할 것 ab의 길이 사이의 최소값까지. ab의 길이가 같지 않을 때 영향을줍니다.

+0

이 매우 익숙 않습니다 시퀀스는 "구멍"거기에, 구멍을 채우기 위해 itertools.zip_longest를 사용 (None에 채우기 값 기본값 만 지정 될 수 있습니다)가 다양한 예제와 문서 페이지에서 – will

+0

그건 pythonic :) 확인합니다! –

4

zip 대신에 Numpy을 사용할 수 있습니다. 특히 속도가 중요하고 긴 배열이있는 경우에는 특히 유용합니다. 그것 훨씬 더 빨리 당신은 당신이 루프를하지 않아도, 그냥 쓸 수 NumPy와 배열을 사용하면 :

print a + b 

을 표시하는 그래프는 우편, izip 및 NumPy와를 사용하여 길이가 다른 목록을 합산위한 타이밍 평균 : enter image description here

+1

나는 numpy에 관해 알고있다. 이 경우에는 분명히 적용 할 수 있지만 예제는 고의적 인 것입니다. 내가 정말로 원했던 것은 두 개의 객체 목록이 있고 둘 다의 n 번째 객체에 액세스하려고 할 때입니다. 'matplotlib' piechart에서'wedges'에''hatch' 패턴을 추가하고자 할 때 그것이 나에게 분명해졌습니다. 최종 용도는'패턴, 쐐기 모양의 지퍼 (패턴, 쐐기) : wedge.set_hatch (pattern)'와 같은 것입니다. – will

0

numpy 이래로이 답변을 완벽하게 제공하는 것은 다른 답변에서 논의되었으며, 더 높은 순위의 배열에서 값을 함께 연결하는 것이 유용한 경우가 많습니다.

accepted answer 시퀀스가 ​​listlist의 S 같이 또한 이러한 2 레벨 이상의 numpy 어레이와 같은 다중 레벨 (들이지만, 경우하지만 랭크 1의 모든 시퀀스/배열 움직인다 또는), 각 순위를 반복해야합니다.

import numpy as np 
a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) 
b = np.array([list('abc'), list('pdq'), list('xyz')]) 
c = np.array([[frobnicate(aval, bval) for aval, bval in zip(arow, brow)] for arow, brow in zip(a, b)]) 

와 동일한 형상의 이차원 중첩 시퀀스 중 어느 세트에 대해 작동 동일한 개념 : 아래 차원 numpy 배열 예이다

a = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] 
b = [list('abc'), list('pdq'), list('xyz')] 
c = [[frobnicate(aval, bval) for aval, bval in zip(arow, brow)] for arow, brow in zip(a, b)] 

하나 중첩의 양이면

from itertools import zip_longest as zipl 
a = [[], [4, 5, 6], [7, 8, 9]] # empty list in the first row 
b = [list('abc'), list('pdq'), []] # empty list in the last row 
c = [[frobnicate(aval, bval) for aval, bval in zipl(arow, brow)] for arow, brow in zipl(a, b)] 
관련 문제