단일 리스트의 쌍
저는 종종 쌍으로 목록을 처리해야 할 필요성을 발견했습니다.저는 어떤 것이 그것을 하는 데 있어 비단결적이고 효율적인 방법일지 궁금했고, 구글에서 이것을 발견했습니다.
pairs = zip(t[::2], t[1::2])
저는 그것이 충분히 부정적이라고 생각했지만, 관용구 대 효율성에 대한 최근의 토론 후에, 저는 몇 가지 테스트를 하기로 결정했습니다.
import time
from itertools import islice, izip
def pairs_1(t):
return zip(t[::2], t[1::2])
def pairs_2(t):
return izip(t[::2], t[1::2])
def pairs_3(t):
return izip(islice(t,None,None,2), islice(t,1,None,2))
A = range(10000)
B = xrange(len(A))
def pairs_4(t):
# ignore value of t!
t = B
return izip(islice(t,None,None,2), islice(t,1,None,2))
for f in pairs_1, pairs_2, pairs_3, pairs_4:
# time the pairing
s = time.time()
for i in range(1000):
p = f(A)
t1 = time.time() - s
# time using the pairs
s = time.time()
for i in range(1000):
p = f(A)
for a, b in p:
pass
t2 = time.time() - s
print t1, t2, t2-t1
다음은 제 컴퓨터의 결과입니다.
1.48668909073 2.63187503815 1.14518594742
0.105381965637 1.35109519958 1.24571323395
0.00257992744446 1.46182489395 1.45924496651
0.00251388549805 1.70076990128 1.69825601578
만약 내가 그것들을 올바르게 해석하고 있다면, 그것은 Python에서 목록, 목록 인덱싱 및 목록 슬라이싱의 구현이 매우 효율적이라는 것을 의미합니다.그것은 위안이 되기도 하고 예상치도 못한 결과입니다.
목록을 쌍으로 이동하는 "더 나은" 다른 방법이 있습니까?
리스트에 홀수의 요소가 있는 경우 마지막 요소는 쌍에 포함되지 않습니다.
모든 요소가 포함되도록 보장하는 올바른 방법은 무엇입니까?
저는 테스트에 대한 답변에서 다음 두 가지 제안을 추가했습니다.
def pairwise(t):
it = iter(t)
return izip(it, it)
def chunkwise(t, size=2):
it = iter(t)
return izip(*[it]*size)
결과는 다음과 같습니다.
0.00159502029419 1.25745987892 1.25586485863
0.00222492218018 1.23795199394 1.23572707176
지금까지의 결과
가장 단순하고 효율적입니다.
pairs = izip(t[::2], t[1::2])
가장 효율적이고 매우 부정적입니다.
pairs = izip(*[iter(t)]*2)
첫 번째 답변은 두 번의 반복을 사용하고 두 번째 답변은 한 번의 반복을 사용한다는 사실에 잠시 시간이 걸렸습니다.
한 개의 홀수요가시처를위기해리하퀀하, 증시원요것다를니가습추었이퀀는시스키래, 는가소나하의를제안의은소를진스▁to▁(▁the▁adding▁one홀▁element▁the,▁with▁original▁sequence것다▁number▁of▁been▁augment▁an▁to▁elements)를 추가하는 것이 되었습니다.None
으로, 이를 할 수 있는 것입니다.itertools.izip_longest()
.
마침내.
에서는 Python 3.x를 zip()
처럼 합니다.itertools.izip()
,그리고.itertools.izip()
사라졌습니다.
내가 가장 좋아하는 방법:
def pairwise(t):
it = iter(t)
return zip(it,it)
# for "pairs" of any length
def chunkwise(t, size=2):
it = iter(t)
return zip(*[it]*size)
모든 요소를 쌍으로 구성하려는 경우 분명히 채우기 값이 필요할 수 있습니다.
from itertools import izip_longest
def blockwise(t, size=2, fillvalue=None):
it = iter(t)
return izip_longest(*[it]*size, fillvalue=fillvalue)
3, Python 3을 하는 경우itertools.izip
는 간단히 이제간게하단▁now▁is게간.zip
파이썬으로 작업하려면 합니다.
from itertools import izip as zip
당신의 초기 해결책은pairs = zip(t[::2], t[1::2])
에 (에서, 가읽에쉽가것그다좋니입은장문는에기때기장파썬고서이리▁(에그▁it▁is▁the,▁because다and▁3▁best 3▁one서는,zip
목록 대신 반복기를 자동으로 반환합니다.
모든 요소가 포함되도록 하려면 목록을 다음과 같이 확장하면 됩니다.None
.
가 있을 쌍은 그다음목홀요의있마쌍은지막으면소가 .(item, None)
.
>>> t = [1,2,3,4,5]
>>> t.append(None)
>>> zip(t[::2], t[1::2])
[(1, 2), (3, 4), (5, None)]
>>> t = [1,2,3,4,5,6]
>>> t.append(None)
>>> zip(t[::2], t[1::2])
[(1, 2), (3, 4), (5, 6)]
작은 고지 사항부터 시작하겠습니다. 아래 코드를 사용하지 마십시오.그건 전혀 파이썬이 아니에요, 그냥 재미로 쓴 거예요.@THC4k와 유사합니다.pairwise
기능을 하지만 사용합니다.iter
그리고.lambda
폐쇄.사용하지 않습니다.itertools
모듈 및 지원하지 않음fillvalue
누군가가 흥미롭게 여길지도 모르기 때문에 여기에 두었습니다.
pairwise = lambda t: iter((lambda f: lambda: (f(), f()))(iter(t).next), None)
>>> my_list = [1,2,3,4,5,6,7,8,9,10]
>>> my_pairs = list()
>>> while(my_list):
... a = my_list.pop(0); b = my_list.pop(0)
... my_pairs.append((a,b))
...
>>> print(my_pairs)
[(1, 2), (3, 4), (5, 6), (7, 8), (9, 10)]
대부분의 파이썬에 관한 한, 저는 파이썬 소스 문서에서 제공되는 레시피(일부는 @Jochen Ritzel이 제공한 답변과 매우 유사함)가 아마도 최선의 방법이라고 생각합니다.
def grouper(iterable, n, fillvalue=None):
"Collect data into fixed-length chunks or blocks"
# grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx
args = [iter(iterable)] * n
return izip_longest(fillvalue=fillvalue, *args)
현대 파이썬에서는 그냥 사용하면 됩니다.zip_longest(*args, fillvalue=fillvalue)
해당 문서 페이지에 따라.
목록을 쌍으로 이동하는 "더 나은" 다른 방법이 있습니까?
확실하게 말할 수는 없지만 의심스럽습니다.다른 모든 트래버설에는 해석해야 하는 더 많은 파이썬 코드가 포함됩니다.zip()과 같은 내장 기능은 C로 작성되어 훨씬 빠릅니다.
모든 요소가 포함되도록 보장하는 올바른 방법은 무엇입니까?
목록의 길이를 확인하고 이상한지 확인합니다(len(list) & 1 == 1
목록을 복사하고 항목을 추가합니다.
다음만 수행:
>>> l = [1, 2, 3, 4, 5, 6]
>>> [(x,y) for x,y in zip(l[:-1], l[1:])]
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 6)]
다음은 제너레이터를 사용하여 쌍/레그를 만드는 예입니다.제너레이터에 스택 제한 없음
def pairwise(data):
zip(data[::2], data[1::2])
예:
print(list(pairwise(range(10))))
출력:
[(0, 1), (2, 3), (4, 5), (6, 7), (8, 9)]
알고리즘적으로 답이 필요한 경우를 대비하여 다음과 같이 설명합니다.
>>> def getPairs(list):
... out = []
... for i in range(len(list)-1):
... a = list.pop(0)
... for j in a:
... out.append([a, j])
... return b
>>>
>>> k = [1, 2, 3, 4]
>>> l = getPairs(k)
>>> l
[[1, 2], [1, 3], [1, 4], [2, 3], [2, 4], [3, 4]]
그러나 사용자가 사용했기 때문에 원래 목록도 마지막 요소로 축소됩니다.pop
그 위에
>>> k
[4]
이 토막글은 저에게 효과가 있었습니다.목록 길이가 홀수인 경우 튜플 쌍을 만들고 빈 문자열을 마지막 쌍에 추가합니다.fillvalue=""
).
zip_longest(*[iter(my_list)] * 2, fillvalue="")
# odd
list(zip_longest(*[iter([0, 1, 2, 3, 4, 5, 6])] * 2, fillvalue=""))
[(0, 1), (2, 3), (4, 5), (6, '')]
# even
list(zip_longest(*[iter([0, 1, 2, 3, 4, 5])] * 2, fillvalue=""))
[(0, 1), (2, 3), (4, 5)]
언급URL : https://stackoverflow.com/questions/4628290/pairs-from-single-list
'programing' 카테고리의 다른 글
*ngIf를 사용하여 angular 2 템플릿에서 빈 객체를 확인하는 방법 (0) | 2023.07.26 |
---|---|
passport.session() 미들웨어는 무엇을 합니까? (0) | 2023.07.26 |
Ajax 요청 문제: 오류 800001 (0) | 2023.07.26 |
MariaDB - 기술 통계량에 대한 왜도 및 첨도 얻기 (0) | 2023.07.26 |
npm 글로벌 경로 접두사 (0) | 2023.07.26 |