티스토리 뷰

반응형

파이썬을 공부하러 인터넷을 돌아다니다 흥미로운 걸 보게 되었다.

 

지능형 리스트(list comprehension)를 쓰느냐, map 함수를 쓰느냐에서 지능형 리스트를 쓰는 게 좋다는 것.

사실 지능형 리스트는 for 문이 들어가 있어서 map 함수를 쓰는 게 좋다고 생각했는데, 아니었다.

 

a = [sum(i) for i in s if i>20]

b = list(filter(lambda x x>20, map(sum,s))

 

만약에 리스트 내에 for 문이 들어 있는 값을 할당한다면, 무조건 리스트 컴프리 헨션이 빠르다.

이는 데이터 값이 많을수록 차이가 훨씬 난다.

 

https://testspoon.tistory.com/186

 

RePythonOOP 9일차 파이썬 컨테이너 VS 플랫, 가변 VS 불변, 리스트 컴프리 핸션

Insight 1. 리스트내에 for문을 통한 값 할당시 무조건 (지능형) 리스트 컴프리 핸션이 빠르다. 2. 가변 불변, 컨테이너, 플랫은 자주 보면서 외우려고 마음을 먹었다. (중요하고 나중에 다시 찾아 볼

testspoon.tistory.com

 

해당 글을 보면, 직접 어셈블리어를 비교해놓은 글도 볼 수 있다.

for문은 함수 자체가 실행 시 전체 프로세스가 반복이라 느리다.

반면에 리스트 컴프리헨션은 먼저 사용할 변수를 적재하고, 함수를 실행한다.

이 과정은 map도 마찬가지긴 하지만, 적재할 함수와 변수가 리스트 컴프리헨션보다 많아서 메모리 누적을 유발한다.

from dis import dis
# 빈리스트에 for문에서 append()사용 시 
print(dis('''
list_ = []
for i in range(10):
    list_.append(i)
'''))

# ----------------동기적 진행?--------------------
#   2           0 BUILD_LIST               0
#               2 STORE_NAME               0 (list_)

#   3           4 SETUP_LOOP              26 (to 32)
#               6 LOAD_NAME                1 (range)
#               8 LOAD_CONST               0 (10)
#              10 CALL_FUNCTION            1
#              12 GET_ITER
#         >>   14 FOR_ITER                14 (to 30)
#              16 STORE_NAME               2 (i)

#   4          18 LOAD_NAME                0 (list_)
#              20 LOAD_METHOD              3 (append)
#              22 LOAD_NAME                2 (i)
#              24 CALL_METHOD              1
#              26 POP_TOP
#              28 JUMP_ABSOLUTE           14
#         >>   30 POP_BLOCK
#         >>   32 LOAD_CONST               1 (None)
#              34 RETURN_VALUE
# None



# 리스트 컴프리핸션
print(dis('[i for i in range(10) if i%2 == 0]'))
# -------------- 변수 적재,함수 호출과정-----------------
#   1           0 LOAD_CONST               0 (<code object <listcomp> at 0x7f146c1015d0, file "<dis>", line 1>)
#               2 LOAD_CONST               1 ('<listcomp>')
#               4 MAKE_FUNCTION            0
#               6 LOAD_NAME                0 (range)
#               8 LOAD_CONST               2 (10)
#              10 CALL_FUNCTION            1
#              12 GET_ITER
#              14 CALL_FUNCTION            1
#              16 RETURN_VALUE

# ----------- 함수 실행과정-----------------------
# Disassembly of <code object <listcomp> at 0x7f146c1015d0, file "<dis>", line 1>:
#   1           0 BUILD_LIST               0
#               2 LOAD_FAST                0 (.0)
#         >>    4 FOR_ITER                20 (to 26)
#               6 STORE_FAST               1 (i)
#               8 LOAD_FAST                1 (i)
#              10 LOAD_CONST               0 (2)
#              12 BINARY_MODULO
#              14 LOAD_CONST               1 (0)
#              16 COMPARE_OP               2 (==)
#              18 POP_JUMP_IF_FALSE        4
#              20 LOAD_FAST                1 (i)
#              22 LIST_APPEND              2
#              24 JUMP_ABSOLUTE            4
#         >>   26 RETURN_VALUE
# None


print(dis('list(filter(lambda i : i%2 == 0 , map(int, range(10))))'))
# -------------- 변수 적재,함수 호출과정-----------------
#   1           0 LOAD_NAME                0 (list)
#               2 LOAD_NAME                1 (filter)
#               4 LOAD_CONST               0 (<code object <lambda> at 0x7f146c1015d0, file "<dis>", line 1>)
#               6 LOAD_CONST               1 ('<lambda>')
#               8 MAKE_FUNCTION            0
#              10 LOAD_NAME                2 (map)
#              12 LOAD_NAME                3 (int)
#              14 LOAD_NAME                4 (range)
#              16 LOAD_CONST               2 (10)
#              18 CALL_FUNCTION            1
#              20 CALL_FUNCTION            2
#              22 CALL_FUNCTION            2
#              24 CALL_FUNCTION            1
#              26 RETURN_VALUE

# ----------- 함수 실행과정-----------------------
# Disassembly of <code object <lambda> at 0x7f146c1015d0, file "<dis>", line 1>:
#   1           0 LOAD_FAST                0 (i)
#               2 LOAD_CONST               1 (2)
#               4 BINARY_MODULO
#               6 LOAD_CONST               2 (0)
#               8 COMPARE_OP               2 (==)
#              10 RETURN_VALUE

 

따라서 map 함수니 for을 굳이 사용해야 하는 상황이 아니라면, 파이썬에서는 리스트 컴프리헨션 사용을 습관 들이는 게 좋을 듯 싶다.

 

반응형