파이썬/기본문법

파이썬 이중, 다중 리스트 1차원 리스트 하나로 만들기

코데방 2024. 3. 25.
728x90

for문을 이용한 방법

 

먼저 반복문을 이용해 하나씩 순회하면서 내용을 꺼내와 새로운 리스트에 담아주는 방법입니다. 가장 기본입니다. 다차원 구조일 수록 for문이 늘어나게됩니다. 

lst = [[1,2,3,4,5], ["a","b","c","d"]]

lst_1d = []
for i in lst:
    for j in i:
        lst_1d.append(j)

 

 

 

위 구문을 한 줄로 작성하면 아래와 같이 쓸 수 있습니다.

lst = [[1,2,3,4,5], ["a","b","c","d"]]
lst_1d = [j for i in lst for j in i]

 

 

 

 

위와 같이 하나씩 추가해줄 때는 리스트의  append()를 사용합니다. 리스트가 제공하는 extend()를 사용하면 리스트를 리스트 안에 추가하더라도 다차원 리스트가 아닌 1차원 리스트로 만들어줍니다. 

lst_1d = []
for i in lst:
    lst_1d.extend(i)

 

 

 

다만 3중, 3차원 리스트의 경우에는 또 다시 다차원 리스트가 됩니다. 

lst = [[1,2,3,4,["가", "나", "다", "라"]], ["a","b","c","d"]]

lst_1d = []
for i in lst:
    lst_1d.extend(i)

 

 

 

아래와 같이 최종 차원 계수를 알지만 모양이 불규칙한 다중 리스트의 경우에는 어쩔 수 없이 가장 위의 다중 for문을 이용해 로직으로 걸러주는 수밖에 없을 듯합니다. 

lst = [[1,2,3,4,["가", "나", "다", "라"]], ["a","b","c","d"]]

lst_1d = []

for i in lst:
    for j in i:
        if type(j) is list:
            lst_1d.extend(j)
        else:
            lst_1d.append(j)

 

 

 

sum 함수를 이용한 방법

 

2중 리스트를 하나의 리스트로 만드는 가장 간단한 방법인 듯합니다. 다만 알고리즘상 시스템 리소스를 상대적으로 많이 사용할 수 있다고 하니 데이터양이 많을 경우 그냥 간단히 한줄짜리 컴프리헨션 for문을 사용하는 것이 더 좋을 것 같습니다.

 

lst = [[1,2,3,4], ["a","b","c","d"]]

lst_1d = sum(lst, [])

 

 

 

 

다중 중첩 리스트 1차원 리스트로 flatten하게 만들기

 

차원수가 일정하게 정해져있는 리스트 구조라면 for문을 이용해 1차원 리스트로 만들기 어렵지 않습니다. 문제는 몇 차원일지 모르는 복잡한 리스트 구조가 있을 때 이를 모두 순회하거나 flatten하게 1차원 구조로 만들어야할 경우입니다.

 

리스트 안 리스트가 몇 차원까지 있는지 알 수 없다고 가정할 때 이를 해결할 수 있는 가장 좋은 방법은 "재귀함수"를 이용하는 것입니다.

 

먼저 아래 완성 코드를 보겠습니다.

 

# 다중 리스트
lst = [[1,2,3,4,["가","나","다","라"]], ["a","b",["c",["d"]]]]


# 리스트 1차원화 재귀함수
def list_flattening(x):
    
    if type(x) is list:
        return [j for i in x for j in list_flattening(i)]
    else:
        return [x]

result = list_flattening(lst)
print(result)

 

 

 

 

좀 어려워보이지만 원리만 알면 간단합니다.

 

두 번째 for문인 "for j in list_flattening(i)"에 들어간 변수가 리스트 타입이 아니면 해당 변수를 배열에 묶어서 리턴시켜주기 때문에 하나의 변수를 가진 리스트 [x]에서 j를 빼와서 리스트에 넣어줍니다.

 

재귀함수에 들어갈 때 가져가는 i가 리스트라면 다시 if문에 걸려 과정을 반복하다가 리스트가 아닌 경우에만 else문에 걸려 변수를 반납해 j로 빠져나와 결과 리스트에 들어가게 되는 것이죠.

 

 

1. x가 리스트이므로 if문에 걸림

2. 리스트의 인덱스 0은 리스트이므로 i는 리스트

3. 리스트이기 때문에 두 번째 for문에서 in 뒤의 배열을 만들기 위해 다시 재귀함수 호출

 

 

 

 

4. 두 번째 호출된 재귀함수에서 파라미터 x의 첫 번째 인덱스인 i는 "1"이므로 else문에 걸려 [1]이 리턴되어 재귀문을 빠져나온 뒤 "for j in [1]"이 완성되어 "j=1"이 최종 리스트에 담기게 됨

 

 

 

 

5. "2,3,4"까지 위와 동일한 과정을 반복하다가 ["가","나","다","라"] 순서가 되면 재귀함수 안에서 다시 if문에 걸리게 되어 한 번 더 위 과정을 수행한 두 빠져나옴. 

 

 

 

 

 

위와 같은 과정을 계속 반복하다 순회가 끝나면 최종 리스트를 리턴하고 함수가 종료됩니다.

 

재귀함수는 완전히 다 이해하기보다는 처음과 마지막 탈출구문만 염두해두고 짜보는게 이해하기 편한 듯합니다. 여러모로 경험이 중요한 듯 하네요~!

 

 

728x90

댓글

💲 추천 글