이 목록 목록을 평면화하고 싶습니다.
[[1, 2, 3], [4, 5, 6], [7], [8, 9]]
안으로:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
이 목록 목록을 평면화하고 싶습니다.
[[1, 2, 3], [4, 5, 6], [7], [8, 9]]
안으로:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
목록 목록이 주어 l
지면
flat_list = [item for sublist in l for item in sublist]
이는 다음을 의미합니다.
flat_list = []
for sublist in l:
for item in sublist:
flat_list.append(item)
지금까지 게시된 바로 가기보다 빠릅니다. ( l
는 병합할 목록입니다.)
다음은 해당 기능입니다.
def flatten(l):
return [item for sublist in l for item in sublist]
timeit
증거로 표준 라이브러리의 모듈을 사용할 수 있습니다 .
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 3: 143 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 3: 969 usec per loop
$ python -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 3: 1.1 msec per loop
설명: 에 기반한 바로 가기는 +
( 에서 암시적인 사용을 포함하여 sum
) L 하위 목록이 있을 때 필연적으로 필요 O(L**2)
합니다. 중간 결과 목록이 계속 길어지면 각 단계에서 새로운 중간 결과 목록 개체가 할당되고 모든 항목이 이전 중간 결과에서 복사해야 합니다(마지막에 몇 가지 새로운 결과가 추가됨). 따라서 단순함과 일반성의 실제 손실 없이 각각 I 항목의 L 하위 목록이 있다고 가정합니다. 총 사본 수는 1에서 L까지 제외된 x에 대한 x의 합을 I 곱한 것입니다. 즉, I * (L**2)/2
.
목록 이해는 하나의 목록을 한 번만 생성하고 각 항목을 (원래 거주지에서 결과 목록으로) 정확히 한 번 복사합니다.
다음 을 사용할 수 있습니다 itertools.chain()
.
>>> import itertools
>>> list2d = [[1,2,3], [4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain(*list2d))
또는 연산자 itertools.chain.from_iterable()
로 목록을 풀지 않아도 되는 which 를 사용할 수 있습니다 .*
>>> import itertools
>>> list2d = [[1,2,3], [4,5,6], [7], [8,9]]
>>> merged = list(itertools.chain.from_iterable(list2d))
이 접근 방식은 틀림없이 다음보다 더 읽기 쉽고 [item for sublist in l for item in sublist]
더 빠른 것처럼 보입니다.
$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;import itertools' 'list(itertools.chain.from_iterable(l))'
20000 loops, best of 5: 10.8 usec per loop
$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' '[item for sublist in l for item in sublist]'
10000 loops, best of 5: 21.7 usec per loop
$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99' 'sum(l, [])'
1000 loops, best of 5: 258 usec per loop
$ python3 -mtimeit -s'l=[[1,2,3],[4,5,6], [7], [8,9]]*99;from functools import reduce' 'reduce(lambda x,y: x+y,l)'
1000 loops, best of 5: 292 usec per loop
$ python3 --version
Python 3.7.5rc1
작성자의 참고 사항 : 이것은 매우 비효율적입니다. 하지만 재미 있습니다. 모노이드 가 굉장하기 때문입니다.
>>> xss = [[1, 2, 3], [4, 5, 6], [7], [8, 9]]
>>> sum(xss, [])
[1, 2, 3, 4, 5, 6, 7, 8, 9]
sum
iterable 의 요소를 합산하고 xss
두 번째 인수를 합에 대한 초기 값으로 사용 []
합니다. (기본 초기값은 0
목록이 아닌 입니다.)
중첩 목록을 합산하기 때문에 실제로 [1,3]+[2,4]
결과로 sum([[1,3],[2,4]],[])
, 이는 와 같습니다 [1,3,2,4]
.
목록 목록에서만 작동합니다. 목록 목록의 경우 다른 솔루션이 필요합니다.