<질문>
한 쌍의 요소를 다시 조정하여 목록을 반복하는 멋진 Python 방법이 있습니까? 마지막 요소는 첫 번째 요소와 쌍을 이루어야합니다.
예를 들어 [1, 2, 3] 목록이있는 경우 다음 쌍을 얻고 싶습니다.
- 1 ~ 2
- 2 ~ 3
- 3-1
<답변1>
쌍으로 목록에 액세스하는 Python 방식은 다음과 같습니다.zip(L, L[1:])
. 마지막 항목을 첫 번째 항목에 연결하려면 :
>>> L = [1, 2, 3]
>>> zip(L, L[1:] + L[:1])
[(1, 2), (2, 3), (3, 1)]
<답변2>
>>> from collections import deque
>>>
>>> l = [1,2,3]
>>> d = deque(l)
>>> d.rotate(-1)
>>> zip(l, d)
[(1, 2), (2, 3), (3, 1)]
<답변3>
나는 약간의 수정을 사용합니다pairwise
레시피에서itertools
documentation:
def pairwise_circle(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ... (s,s0)"
a, b = itertools.tee(iterable)
first_value = next(b, None)
return itertools.zip_longest(a, b,fillvalue=first_value)
이것은 단순히 첫 번째 값에 대한 참조를 유지하고 두 번째 반복자가 소진되면zip_longest
마지막 자리를 첫 번째 값으로 채 웁니다.
(또한 생성기와 같은 반복기뿐만 아니라 목록 / 튜플과 같은 반복자에서도 작동합니다.)
참고@Barry's solution이것과 매우 유사하지만 제 생각에는 이해하기가 더 쉽고 한 요소 이상으로 확장하기가 더 쉽습니다.
<답변4>
나는 페어링 할 것이다itertools.cycle
와zip
:
import itertools
def circular_pairwise(l):
second = itertools.cycle(l)
next(second)
return zip(l, second)
cycle
마지막 값에서 첫 번째 값으로 반복하면서 인수의 값을 순서대로 생성하는 iterable을 반환합니다.
첫 번째 값을 건너 뛰므로 위치에서 시작합니다.1
(보단0
).
다음으로zip
원래의 변형되지 않은 목록과 함께.zip
인수 iterable이 소진되면 중지되기 때문에 좋습니다.
이렇게하면 중간 목록이 생성되지 않습니다.cycle
원본에 대한 참조를 보유하지만 복사하지는 않습니다.zip
같은 방식으로 작동합니다.
입력이 인 경우 중단된다는 점에 유의하는 것이 중요합니다.iterator
, 과 같은file
, (또는map
또는zip
에python-3), 한곳에서 (next(second)
)는 다른 모든 항목에서 자동으로 반복기를 진행합니다. 이것은 다음을 사용하여 쉽게 해결됩니다.itertools.tee
, 원래 이터 러블에 대해 두 개의 독립적으로 작동하는 이터레이터를 생성합니다.
def circular_pairwise(it):
first, snd = itertools.tee(it)
second = itertools.cycle(snd)
next(second)
return zip(first, second)
tee
할 수있다예를 들어, 반환 된 반복기 중 하나가 다른 하나를 건 드리기 전에 다 사용 된 경우 많은 양의 추가 저장소를 사용하지만 한 단계 차이 만 있기 때문에 추가 저장소가 최소화됩니다.
<답변5>
더 효율적인 방법 (임시 목록을 작성하지 않음)이 있지만 이것이 가장 간결하다고 생각합니다.
> l = [1,2,3]
> zip(l, (l+l)[1:])
[(1, 2), (2, 3), (3, 1)]
<답변6>
나는 목록 이해력을 사용하고l[-1]
마지막 요소입니다.
>>> l = [1,2,3]
>>> [(l[i-1],l[i]) for i in range(len(l))]
[(3, 1), (1, 2), (2, 3)]
그런 식으로 임시 목록이 필요하지 않습니다.
<답변7>
쌍을 이루는 순환 파이썬 'for'루프
수락 된 답변이 마음에 들면
zip(L, L[1:] + L[:1])
의미 상 동일한 코드로 훨씬 더 많은 메모리 라이트를 사용할 수 있습니다.itertools
:
from itertools import islice, chain #, izip as zip # uncomment if Python 2
그리고 이것은 원래 목록 이외의 메모리에있는 모든 것을 거의 구체화하지 않습니다 (목록이 상대적으로 크다고 가정).
zip(l, chain(islice(l, 1, None), islice(l, None, 1)))
사용하려면 다음과 같이 소비하십시오 (예 : 목록 사용).
>>> list(zip(l, chain(islice(l, 1, None), islice(l, None, 1))))
[(1, 2), (2, 3), (3, 1)]
이것은 모든 너비로 확장 가능하게 만들 수 있습니다.
def cyclical_window(l, width=2):
return zip(*[chain(islice(l, i, None), islice(l, None, i)) for i in range(width)])
및 사용법 :
>>> l = [1, 2, 3, 4, 5]
>>> cyclical_window(l)
>>> list(cyclical_window(l))
[(1, 2), (2, 3), (3, 4), (4, 5), (5, 1)]
>>> list(cyclical_window(l, 4))
[(1, 2, 3, 4), (2, 3, 4, 5), (3, 4, 5, 1), (4, 5, 1, 2), (5, 1, 2, 3)]
당신은 또한 사용할 수 있습니다tee
중복 순환 객체를 만들지 않으려면 :
from itertools import cycle, tee
ic1, ic2 = tee(cycle(l))
next(ic2) # must still queue up the next item
그리고 지금:
>>> [(next(ic1), next(ic2)) for _ in range(10)]
[(1, 2), (2, 3), (3, 1), (1, 2), (2, 3), (3, 1), (1, 2), (2, 3), (3, 1), (1, 2)]
이것은 매우 효율적이며 예상되는 용도iter
와next
, 우아한 사용법cycle
,tee
, 및zip
.
통과하지 마십시오cycle
직접list
작업을 저장하지 않았고 메모리를 최대로 사용하여 컴퓨터가 정지 할 시간이없는 경우-운이 좋으면 잠시 후 OS가 컴퓨터를 중단하기 전에 프로세스를 종료합니다.
마지막으로 표준 lib 가져 오기는 없지만 원본 목록의 길이까지만 작동합니다 (그렇지 않으면 IndexError).
>>> [(l[i], l[i - len(l) + 1]) for i in range(len(l))]
[(1, 2), (2, 3), (3, 1)]
모듈로를 사용하여 계속할 수 있습니다.
>>> len_l = len(l)
>>> [(l[i % len_l], l[(i + 1) % len_l]) for i in range(10)]
[(1, 2), (2, 3), (3, 1), (1, 2), (2, 3), (3, 1), (1, 2), (2, 3), (3, 1), (1, 2)]
<답변8>
이 문제를 해결하는 방법이 얼마나 많은지 놀랍습니다.
여기 하나 더 있습니다. 사용할 수 있습니다pairwise
레시피로 압축하는 대신b
,chain
이미 튀어 나온 첫 번째 요소와 함께. 그럴 필요 없어cycle
하나의 추가 값이 필요할 때 :
from itertools import chain, izip, tee
def pairwise_circle(iterable):
a, b = tee(iterable)
first = next(b, None)
return izip(a, chain(b, (first,)))
<답변9>
원래 목록을 수정하지 않고 임시 저장소에 목록을 복사하지 않는 솔루션을 좋아합니다.
def circular(a_list):
for index in range(len(a_list) - 1):
yield a_list[index], a_list[index + 1]
yield a_list[-1], a_list[0]
for x in circular([1, 2, 3]):
print x
산출:
(1, 2)
(2, 3)
(3, 1)
나는 이것이 매우 큰 메모리 내 데이터에 사용되는 것을 상상할 수 있습니다.
<답변10>
이것은 목록이l
시스템 메모리의 대부분을 소비했습니다. (무언가이 사건이 불가능하다고 보장한다면, chepner가 게시 한대로 zip을 사용해도됩니다)
l.append( l[0] )
for i in range( len(l)-1):
pair = l[i],l[i+1]
# stuff involving pair
del l[-1]
또는 더 일반적으로 (모든 오프셋에 대해 작동n
즉l[ (i+n)%len(l) ]
)
for i in range( len(l)):
pair = l[i], l[ (i+1)%len(l) ]
# stuff
모듈로 분할이 상당히 빠른 시스템 (즉, 일부 완두콩 내장 시스템이 아님)을 사용하는 경우.
정수 첨자로 목록을 인덱싱하는 것은 비 파이썬 적이며 피하는 것이 가장 좋다는 믿음이 자주있는 것 같습니다. 왜?
<답변11>
이것은 내 솔루션이며 나에게 충분히 Pythonic으로 보입니다.
l = [1,2,3]
for n,v in enumerate(l):
try:
print(v,l[n+1])
except IndexError:
print(v,l[0])
인쇄물:
1 2
2 3
3 1
생성기 기능 버전 :
def f(iterable):
for n,v in enumerate(iterable):
try:
yield(v,iterable[n+1])
except IndexError:
yield(v,iterable[0])
>>> list(f([1,2,3]))
[(1, 2), (2, 3), (3, 1)]
<답변12>
이건 어때요?
li = li+[li[0]]
pairwise = [(li[i],li[i+1]) for i in range(len(li)-1)]
<답변13>
from itertools import izip, chain, islice
itr = izip(l, chain(islice(l, 1, None), islice(l, 1)))
(위와 같이@j-f-sebastian's "zip" answer,하지만 itertools를 사용합니다.)
주의 :편집 됨도움이되는@200_success. 이전 :
itr = izip(l, chain(l[1:], l[:1]))
<답변14>
또 다른 시도
>>> L = [1,2,3]
>>> zip(L,L[1:]) + [(L[-1],L[0])]
[(1, 2), (2, 3), (3, 1)]
<답변15>
너무 많은 메모리를 소비하지 않으려면 내 솔루션을 시도해 볼 수 있습니다.
[(l[i], l[(i+1) % len(l)]) for i, v in enumerate(l)]
조금 느리지 만 메모리를 덜 소비합니다.
<답변16>
곧Python 3.10
release schedule
, 새로운pairwise
함수는 연속 요소의 슬라이딩 쌍을 만드는 방법을 제공합니다.
from itertools import pairwise
# l = [1, 2, 3]
list(pairwise(l + l[:1]))
# [(1, 2), (2, 3), (3, 1)]
또는 간단히pairwise(l + l[:1])
결과가 필요하지 않은 경우list
.
우리는pairwise
머리 (l + l[:1]
) 롤링 쌍이 원형이되도록 (즉,(3, 1)
쌍):
list(pairwise(l)) # [(1, 2), (2, 3)]
l + l[:1] # [1, 2, 3, 1]
<답변17>
L = [1, 2, 3] a = zip (L, L [1 :] + L [: 1]) for i in a : b = list (i) print b
<답변18>
이것은 조합이 일을 할 것 같습니다.
from itertools import combinations
x=combinations([1,2,3],2)
이것은 발전기를 산출 할 것입니다. 그런 다음 반복 할 수 있습니다.
for i in x:
print i
결과는 다음과 같습니다.
(1, 2)
(1, 3)
(2, 3)
'개발 > Python' 카테고리의 다른 글
[파이썬] crontab에 대해 virtualenv를 설정하는 방법은 무엇입니까? (0) | 2021.04.20 |
---|---|
[파이썬] Pydoc으로 문서를 어떻게 만드나요? (0) | 2021.04.20 |
[파이썬] Selenium에서 요소의 속성을 얻는 방법은 무엇입니까? (0) | 2021.04.19 |
[파이썬] jupyter lab에 conda 환경을 추가하는 방법 (0) | 2021.04.19 |