Python에서 길이가 같은 여러 개의 목록 인터리브
파이썬에서 같은 길이의 두 목록을 인터리브할 수 있는 좋은 방법이 있습니까?
내가 주어진다고 해요.[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]
이터 도구 레시피와 함께 제공되는 라이브러리 및
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
저는 다른 크기의 목록으로 이 작업을 수행할 방법이 필요했는데, 이 목록은 승인된 답변에 포함되지 않습니다.
내 솔루션은 제너레이터를 사용하며 그 사용법은 다음과 같습니다.
def interleave(l1, l2):
iter1 = iter(l1)
iter2 = iter(l2)
while True:
try:
if iter1 is not None:
yield next(iter1)
except StopIteration:
iter1 = None
try:
if iter2 is not None:
yield next(iter2)
except StopIteration:
iter2 = None
if iter1 is None and iter2 is 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']
대안:
>>> 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]
저는 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]
다음과 같은 방법도 있습니다.
list1 = [1, 2, 3]
list2 = [10, 20, 30]
list(sum(zip(list1, list2), ()))
그 생각은 비슷합니다.
- 명단을 정리해 주세요(zip 사용)
- 튜플로 납작하게 만들기(합(..., ()) 사용)
- 명부로 전환.
재미있는 접근법은 최종 목록의 위치를 키로 사용하는 것입니다.
from heapq import merge
from itertools import count
a = [1,2,3]
b = [10,20,30]
counter = count()
res = list(merge(a, b, key=lambda x: next(counter)))
print(res)
산출량
[1, 10, 2, 20, 3, 30]
여러 목록의 경우 다음과 같이 압축을 풀 수 있습니다.
from heapq import merge
from itertools import count
a = [1, 2, 3]
b = [10, 20, 30]
c = [11, 21, 31]
counter = count()
res = list(merge(*[a, b, c], key=lambda x: next(counter)))
print(res)
산출량
[1, 10, 11, 2, 20, 21, 3, 30, 31]
[el for el in itertools.chain(*itertools.izip_longest([1,2,3], [4,5])) if el is not None]
이 없으면 None
것.
"파이썬에서 길이가 같은 여러 목록을 인터리브"라는 질문의 제목에 답하기 위해, 우리는 @ekhumoro의 2-list 답변을 일반화할 수 있습니다.따라서 @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]
파티에 너무 늦었고, 좋은 답변들이 많지만, 저는 또한 다음을 사용하여 간단한 해결책을 제공하고 싶습니다.extend()
방법:
list1 = [1, 2, 3]
list2 = [10, 20, 30]
new_list = []
for i in range(len(list1)):
new_list.extend([list1[i], list2[i]])
print(new_list)
출력:
[1, 10, 2, 20, 3, 30]
언급URL : https://stackoverflow.com/questions/7946798/interleave-multiple-lists-of-the-same-length-in-python
'programing' 카테고리의 다른 글
MySQL의 필드 증가는 원자적입니까? (0) | 2023.07.22 |
---|---|
긴 16진수 문자열에서 파이썬 바이트 개체를 만드는 방법은 무엇입니까? (0) | 2023.07.22 |
대응 라우터 및 스프링 부트 컨트롤러로 작업하는 방법 (0) | 2023.07.22 |
외부 "C"는 함수 선언에만 필요합니까? (0) | 2023.07.22 |
라라벨 4 웅변가와 열을 연결하는 방법은 무엇입니까? (0) | 2023.07.22 |