[python] list - flatten
알고리즘 문제를 접하다가, python list 중 3차원 리스트를 2차원 리스트로 변환할 경우가 생겼다
어찌저찌 구현은 했는데, 좀 더 쉬운 방법을 발견해 정리하고자 작성한다.
(1) 함수 sum (간단하게 사용 가능)
(2) list comprehension
[1] 목표 설정
# case 1
[[1], [2, 3]] -> [1, 2, 3]
# case 2
[[[(1, 1), (2, 2)], [(3, 3), (4, 4)]]] -> [[(4, 4), (1, 1), (3, 3), (2, 2)]]
# case 3
([1], [2, 3]) -> [1, 2, 3]
# case 4
[([(1, 1), (2, 2)], [(3, 3), (4, 4)])] -> [[(4, 4), (1, 1), (3, 3), (2, 2)]]
# case 1:
2중 리스트 -> 1중 리스트
# case 2:
3중 리스트 -> 2중 리스트
# case 3:
()를 []로 치환하고 생각했을 때 2중 리스트 -> 1중 리스트
() = tuple 원소를 풀고 싶을 때
# case 4:
()를 []로 치환하고 생각했을 때 3중 리스트 -> 2중 리스트
() = tuple원소를 풀고 싶을 때
(tuple을 푸는 것이 중요한 포인트가 아님
<- list, tuple 모두 iterable 객체이며, iterable객체에 대해 적용 가능한 solution을 살펴볼 것임)
[2] 코드 작성
(1) 함수 sum
sum(iterable객체, start=0)
- iterable 자료형 (list, tuple, dictionary)를 인자로 받고, 해당 객체의 내부 원소들의 합을 반환
- start값 (기본값=0)에서 sum결과값을 더한다
iterable 객체가 한 번 unpacking -> sum -> unpack된 자료형으로 반환 함을 주의하자
또한, [1] + [2, 3] = [1, 2, 3] 임에 주의하자
이러한 sum 함수를 응용하여,
sum(리스트, [])를 수행하여 결과를 도출하는 기법을 사용한다.
# case 1
combinations = [[1], [2, 3]]
print(sum(combinations, []))
# 결과: [1, 2, 3]
- [[1], [2, 3]] -> [1], [2, 3] 로 언패킹
- [1], [2, 3]과 []의 sum 진행 -> [1] + [2, 3] + [] = [1, 2, 3]
# case 2
combinations = [[[(1, 1), (2, 2)], [(3, 3), (4, 4)]]]
print(sum(sum(combinations, []), []))
# 결과: [(1, 1), (2, 2), (3, 3), (4, 4)]
- [[[(1, 1), (2, 2)], [(3, 3), (4, 4)]]] -> [[(1, 1), (2, 2)], [(3, 3), (4, 4)]]로 언패킹
- [[(1, 1), (2, 2)], [(3, 3), (4, 4)]] 과 []의 sum 진행 ->
[[(1, 1), (2, 2)], [(3, 3), (4, 4)]] + [] = [[(1, 1), (2, 2)], [(3, 3), (4, 4)]]
- [[(1, 1), (2, 2)], [(3, 3), (4, 4)]] -> [(1, 1), (2, 2)], [(3, 3), (4, 4)]로 언패킹
- [(1, 1), (2, 2)], [(3, 3), (4, 4)]과 []의 sum 진행 ->
[(1, 1), (2, 2)] + [(3, 3), (4, 4)] + [] = [(1, 1), (2, 2), (3, 3), (4, 4)]
# case 3
combinations = ([1], [2, 3])
print(sum(combinations, []))
# 결과: [1, 2, 3]
- ([1], [2, 3]) -> [1], [2, 3] 로 언패킹
- [1], [2, 3] 과 []의 sum 진행 -> [1] + [2, 3]+ [] = [1, 2, 3]
# case 4
combinations = [([(1, 1), (2, 2)], [(3, 3), (4, 4)])]
print(sum(sum(combinations, ()), []))
# 결과: [(1, 1), (2, 2), (3, 3), (4, 4)]
- [([(1, 1), (2, 2)], [(3, 3), (4, 4)])] -> ([(1, 1), (2, 2)], [(3, 3), (4, 4)])로 언패킹
- ([(1, 1), (2, 2)], [(3, 3), (4, 4)]) 과 ()의 sum 진행 ->
([(1, 1), (2, 2)], [(3, 3), (4, 4)]) + () = ([(1, 1), (2, 2)], [(3, 3), (4, 4)])
- ([(1, 1), (2, 2)], [(3, 3), (4, 4)]) -> [(1, 1), (2, 2)], [(3, 3), (4, 4)]로 언패킹
- [(1, 1), (2, 2)], [(3, 3), (4, 4)]과 []의 sum 진행 ->
[(1, 1), (2, 2)] + [(3, 3), (4, 4)]+ [] = [(1, 1), (2, 2), (3, 3), (4, 4)]
(2) list comprehension
# case 1
combinations = [[1], [2, 3]]
unique_elements = []
for combination in combinations:
flattened_combination = [item for item in combination]
unique_elements.extend(list(flattened_combination))
print(unique_elements)
# 결과: [1, 2, 3]
# case 2
combinations = [[[(1, 1), (2, 2)], [(3, 3), (4, 4)]]]
unique_elements = []
for combination in combinations:
flattened_combination = [item for sublist in combination for item in sublist]
unique_elements.extend(list(flattened_combination))
print(unique_elements)
# 결과: [(1, 1), (2, 2), (3, 3), (4, 4)]
- 순서 주의: (1) combination의 원소 sublist에 대해, (2) sublist의 원소 item에 대해, (3) item 반환
# case 3
combinations = ([1], [2, 3])
unique_elements = []
for combination in combinations:
flattened_combination = [item for item in combination]
unique_elements.extend(list(flattened_combination))
print(unique_elements)
# 결과: [1, 2, 3]
# case 4
combinations = [([(1, 1), (2, 2)], [(3, 3), (4, 4)])]
unique_elements = []
for combination in combinations:
flattened_combination = [item for sublist in combination for item in sublist]
unique_elements.extend(list(flattened_combination))
print(unique_elements)
# 결과: [(1, 1), (2, 2), (3, 3), (4, 4)]
[3] 결론
list를 flattern하는 방법의 가장 중요한 점은 iterable 객체를 unpacking 하는 것이다.
(1) 이때 함수 sum은 함수 특성상 1회 자동 unpacking이 수행되고 + 연산을 진행한댜.
또한 list의 + 연산은 예를 들어 [1] + [2, 3] = [1, 2, 3]과 같이 하나의 리스트로 반환함을 기억해야 한다.
이것을 사용하면 간편하게 flatten을 수행할 수 있다.
(2) 또한 sum이 아니더라도, list comprehension을 통해 iterable객체의 원소를 하나씩 접근해 차원을 바꿀 수도 있다.