본문 바로가기

컴퓨터/파이썬 공부정리

[Python] flatten 구현 - non-iterative, recursive function

import time

def flat(lst):
    i=0
    while i<len(lst):
        while True:
            try:
                lst[i:i+1] = lst[i] 
            except (TypeError, IndexError):
                break
        i += 1

if __name__ == "__main__":
    start = time.time()
    data = [1,[-2,[[4]], [0,5], [],3],[4],2,7] * 100000
    sum = 0
    flat(data)
    i = 0
    while True:
        e = data[i]
        print(e, end=' ')
        sum += e
        if sum > 10:
            break
        i += 1   
    print('\nResult :', sum)
    print(f'time : {(time.time()-start) * 1000}')

while을 통하여 리스트를 하나씩 불러와서 검사합니다.

 

다만 검사 방법에서 slicing assignment을 이용합니다.

 

list[1:2] list[1]은 같은 인덱스 1에 대한 것이지만 그 결과값은 다릅니다.

 

예를 들어, list = [1,2,3]에 대하여 list[1:2] = [1]를 의미하지만, list[1] = 1, slicing assignment를 통해 나타나는 결과는 리스트인 반면, 인덱스로 접근하면 값을 보여줍니다.

 

따라서 slicing assignment로 요소를 할당하기 위해선 r-value가 시퀀스 객체이여야 합니다.

 

list = [1,2,3,[4,5]]의 경우에서, list[3][4,5]이므로 시퀀스 객체입니다. 따라서 list[3:4] =list[3]의 결과로 인덱스 3~4에 대하여 4,5 값이 저장됩니다.

 

하지만 다음 list[3]에 대하여 list[3] = 4 이므로 시퀀스 객체가 아닙니다.

 

이 경우 TypeError가 발생합니다. 3번 코드에선 이 TypeError에 대해 break를 함으로써 주어진 인덱스에 대해서 더 이상 flatten을 할 필요가 없음을 알리고 인덱스+1을 진행하여 다음 인덱스에 대한 flatten을 진행하게 됩니다.

 

본 코드는 ROSETTACODE.ORG(https://rosettacode.org/wiki/Flatten_a_list#Python)에서 제작한 Python non-recursive 코드를 인용하였습니다.