Python에서 길이가 같은 여러 목록을 인터리브
어느 곳에서 길이가 같은 두 목록을 인터리브하는 좋은 방법이 있습니까?
I 'm 주어진 [1,2,3]
하고 [10,20,30]
. 나는 성가시다 [1,10,2,20,3,30]
.
질문을 게시 한 후 다음을 수행 할 수 있다고 생각합니다.
[val for pair in zip(l1, l2) for val in pair]
경우 l1
와 l2
두 목록입니다.
인터리브 할 목록이 N 개이면
lists = [l1, l2, ...]
[val for tup in zip(*lists) for val in tup]
더 많은 레시피를 보려면 접미사 값으로 목록을 인터리브하는 가장 좋은 방법을 보고세요 . 거기에서 설명 된 방법 중 일부는 동일한 길이의 두 개 이상의 목록으로 일반화 될 수 있습니다.
Python> = 2.3의 경우 확장 된 내부 구문이 있습니다 .
>>> a = [0, 2, 4, 6, 8]
>>> b = [1, 3, 5, 7, 9]
>>> c = a + b
>>> c[::2] = a
>>> c[1::2] = b
>>> c
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
줄 c = a + b
은 내용 길이의 새 목록을 만드는 방법으로 사용됩니다. (이 단계에서는 내용이 중요하지 않습니다.) 다음 두 줄은 인터리빙의 실제 수행 a
과 b
: 첫 번째는 작업 에 할당 a
된 모든 짝수 작업에를 c
; 두 번째는 b
모든 홀수 수준에 의 요소를 할당합니다 c
.
주어진
a = [1, 2, 3]
b = [10, 20, 30]
c = [100, 200, 300, 999]
암호
길이가 같은 목록을 가정하면 itertools.chain
및 zip
다음을 사용 하여 인터리브 된 목록을 얻을 수 있습니다 .
import itertools
list(itertools.chain(*zip(a, b)))
# [1, 10, 2, 20, 3, 30]
대안
일반적으로 같지 않은 목록의 경우 다음을 사용하십시오 zip_longest
(권장).
[x for x in itertools.chain(*itertools.zip_longest(a, c)) if x is not None]
# [1, 100, 2, 200, 3, 300, 999]
많은 목록을 고용주 인터리브 할 수 있습니다.
[x for x in itertools.chain(*itertools.zip_longest(a, b, c)) if x is not None]
# [1, 10, 100, 2, 20, 200, 3, 30, 300, 999]
roundrobin
itertools 레시피 와 함께 제공되는 라이브러리 및 .interleave
interleave_longest
import more_itertools
list(more_itertools.roundrobin(a, b))
# [1, 10, 2, 20, 3, 30]
list(more_itertools.interleave(a, b))
# [1, 10, 2, 20, 3, 30]
list(more_itertools.interleave_longest(a, c))
# [1, 100, 2, 200, 3, 300, 999]
yield from
마지막으로 Python 3에서 흥미로운 점 (권장되지 않은 현상) :
list(filter(None, ((yield from x) for x in zip(a, b))))
# [1, 10, 2, 20, 3, 30]
list([(yield from x) for x in zip(a, b)])
# [1, 10, 2, 20, 3, 30]
+ 사용하여 설치pip install more_itertools
대안 :
>>> l1=[1,2,3]
>>> l2=[10,20,30]
>>> [y for x in map(None,l1,l2) for y in x if y is not None]
[1, 10, 2, 20, 3, 30]
이것은 지도 가 목록에서 병렬로 작동하기 때문에 작동합니다. 그것은 동일하게 작동 2.2에서. 자체적으로 None
호출 된 함수 map
로 튜플 목록을 생성합니다.
>>> map(None,l1,l2,'abcd')
[(1, 10, 'a'), (2, 20, 'b'), (3, 30, 'c'), (None, None, 'd')]
그런 다음 튜플 목록을 평면화하십시오.
물론 장점 map
은 목록의 수에 관계없이 작동하며 길이가 다른 경우에도 작동한다는 것입니다.
>>> l1=[1,2,3]
>>> l2=[10,20,30]
>>> l3=[101,102,103,104]
>>> [y for x in map(None,l1,l2,l3) for y in x if y in not None]
[1, 10, 101, 2, 20, 102, 3, 30, 103, 104]
나는 수용된 대답이 다루지 않는 다른 크기의 목록으로 수행하는 방법이 필요했습니다.
내 솔루션은 생성기를 사용하고 그 사용은 그 때문에 약간 더 좋아합니다.
def interleave(l1, l2):
iter1 = iter(l1)
iter2 = iter(l2)
while True:
try:
if iter1 != None:
yield next(iter1)
except StopIteration:
iter1 = None
try:
if iter2 != None:
yield next(iter2)
except StopIteration:
iter2 = None
if iter1 == None and iter2 == None:
raise StopIteration()
그리고 그 사용법 :
>>> a = [1, 2, 3, 4, 5]
>>> b = ['a', 'b', 'c', 'd', 'e', 'f', 'g']
>>> list(interleave(a, b))
[1, 'a', 2, 'b', 3, 'c', 4, 'd', 5, 'e', 'f', 'g']
>>> list(interleave(b, a))
['a', 1, 'b', 2, 'c', 3, 'd', 4, 'e', 5, 'f', 'g']
나는 aix의 솔루션을 가장 좋아합니다. 2.2에서 작동해야 생각하는 또 다른 방법이 있습니다.
>>> x=range(3)
>>> x
[0, 1, 2]
>>> y=range(7,10)
>>> y
[7, 8, 9]
>>> sum(zip(x,y),[])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "tuple") to list
>>> sum(map(list,zip(x,y)),[])
[0, 7, 1, 8, 2, 9]
한 가지 더 방법 :
>>> a=[x,y]
>>> [a[i][j] for j in range(3) for i in (0,1)]
[0, 7, 1, 8, 2, 9]
과 :
>>> sum((list(i) for i in zip(x,y)),[])
[0, 7, 1, 8, 2, 9]
[el for el in itertools.chain(*itertools.izip_longest([1,2,3], [4,5])) if el is not None]
당신이없는만큼 None
유지하려는 것을
"파이썬에서 같은 길이의 여러 목록을 인터리브"라는 질문의 제목에 답하기 위해 @ekhumoro의 2 개 목록 답을 일반화 할 수 있습니다. 이를 위해서는 @NPE의 (우아한) 솔루션과 달리 목록의 길이가 동일해야합니다.
import itertools
def interleave(lists):
"""Interleave a list of lists.
:param lists: List of lists; each inner length must be the same length.
:returns: interleaved single list
:rtype: list
"""
if len(set(len(_) for _ in lists)) > 1:
raise ValueError("Lists are not all the same length!")
joint = list(itertools.chain(*lists))
for l_idx, li in enumerate(lists):
joint[l_idx::len(lists)] = li
return joint
예 :
>>> interleave([[0,2,4], [1, 3, 5]])
[0, 1, 2, 3, 4, 5]
>>> interleave([[0,2,4], [1, 3, 5], [10, 11, 12]])
[0, 1, 10, 2, 3, 11, 4, 5, 12]
>>> interleave([[0,2,4], [1, 3, 5], [10, 11, 12], [13, 14, 15]])
[0, 1, 10, 13, 2, 3, 11, 14, 4, 5, 12, 15]
>>> interleave([[0,2,4], [1, 3, 5], [10, 11, 12], [13, 14]])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 10, in interleave
ValueError: Lists are not all the same length!
>>> interleave([[0,2,4]])
[0, 2, 4]
참고 URL : https://stackoverflow.com/questions/7946798/interleave-multiple-lists-of-the-same-length-in-python
'ProgramingTip' 카테고리의 다른 글
Webkit CSS 애니메이션 문제-애니메이션의 최종 상태를 유지합니까? (0) | 2020.10.31 |
---|---|
IntelliJ 정적 가져 오기 완료 (0) | 2020.10.31 |
Dapper.Net에서 일대 다 쿼리를 어떻게 작성합니까? (0) | 2020.10.31 |
HierarchyViewer가 Samsung Galaxy TAB 7.0에서 작동하지 않는 이유는 무엇입니까? (0) | 2020.10.31 |
Python에서 PDFMiner를 사용하여 PDF 파일에서 텍스트 추출? (0) | 2020.10.31 |