Python TIL(5) - Removing vs Slicing

random·2021년 3월 23일
0

Python - TIL

목록 보기
5/19

Removing vs Slicing

리스트를 하나하나 제거 하는 루프와, 슬라이싱을 비교해서 어느 것이 더 효율적인가 따져보자.


import timeit
 
max_value = 100  # 100000000 으로도 시도해봄
min_valid = 10
max_valid = 97  # 99999997 으로도 시도해봄
 
data_list1 = list(range(max_value))
data_list2 = list(range(max_value))
data_list3 = list(range(max_value))
 
 
def sanitise_1(data):
    # process the low values in the list
    stop = 0
    for index, value in enumerate(data):
        if value >= min_valid:
            stop = index
            break
 
    del data[:stop]
 
    start = 0
    for index in range(len(data) - 1, -1, -1):
        if data[index] <= max_valid:
            # We have the index of last item to keep.
            # Set 'start' to the position of the first
            # item to delete, which is 1 after 'index'.
            start = index + 1
            break
 
    del data[start:]
 
 
def sanitise_2(data):
    top_index = len(data) - 1
    for index, value in enumerate(reversed(data)):
        if value < min_valid or value > max_valid:
            del data[top_index - index]
 
 
def sanitise_3(data):
    for index in range(len(data) - 1, -1, -1):
        if data[index] < min_valid or data[index] > max_valid:
            del data[index]
 
 
 
if __name__ == "__main__":
    print("Timing")
    x = timeit.timeit("sanitise_1(data_list1)",
                      setup="from __main__ import sanitise_1,"
                            "data_list1",
                      number=1)
    print("{:15.15f}".format(x))
    y = timeit.timeit("sanitise_2(data_list2)",
                      setup="from __main__ import sanitise_2,"
                            "data_list2",
                      number=1)
    print("{:15.15f}".format(y))
    z = timeit.timeit("sanitise_3(data_list3)",
                      setup="from __main__ import sanitise_3,"
                            "data_list3",
                      number=1)
    print("{:15.15f}".format(z))
 
    

위 소스코드에서는, 아래의 3가지 방법을 써서 index, item 슬라이싱의 여러가지 방법 중 서로간의 효율성을 따져보았음. 간략히 설명하자면, 방대한 range 범위내에서

1번 방법: for + enumerate // for + range 함수 2개 쓰기 (min_value, max_value를 합집합으로 안넣고 따로 씀)
2번 방법: for + enumerate + reverse 함수 쓰기
3번 방법: for + range 함수 1개쓰기 (min_value, max_value를 합집합으로 넣어서 한 줄로 씀)

  • 현재로서는 위 3개 중 1>3>2 순으로 효율적인 코드임. (Time complexity wise)
    코드는 두 줄로 만들어지고 조금 더 길지언정 효율성은 제일 높음!
    *작은 사이즈의 데이터 출력소모시간(100 입력):
    0.000006422000000
    0.000020761000000
    0.000014511000000

  • 하지만 여기서 반전은, enumerate 함수는 데이터 값이 커지면 더 효율적인 방법이 됨. 따라서 데이터 값이 예를 들어 10000 이상 넘어갈 시 효율성은 1>2>3 순이 됨. 뒤 두 주자가 순서가 바뀜.
    *보다 큰 사이즈의 데이터 출력소모시간(10000 입력):
    0.000010815000000
    0.000912805000000
    0.001433718000000

  • 그 까닭은, 아이템을 하나씩 one by one delete 하는 것 보다 한 번에 범위를 설정해서 슬라이싱 하는게 훨씬 효율적인 방법임. 대용량 데이터 다룰 시 참고할 것!

0개의 댓글