-
Python - List Comprehension(리스트 표현식)프로그래밍/Python 2021. 6. 4. 16:14반응형
List Comprehensions : 리스트 표현식
리스트 표현식은 리스트를 만드는 간결한 방식을 제공합니다.
비교 : 리스트 표현식과 기존의 방식들
예제 : 0~10의 제곱수를 담은 squares라는 리스트를 만들어보자.
<기존 방식1 : claasic>
squares = [] for x in range(10): squares.append(x**2)
문제점 : x라는 변수가 loop 이후에도 존재.
<기존 방식2: 위 문제점 해결>
squares = list(map(lambda x: x**2, range(10)))
<리스트 표현식>
squares = [x**2 for x in range(10)]
방식2와 비교하였을 때, 보다 간결하고 가독성이 뛰어나다는 것을 알 수 있습니다.
리스트 표현식(listcomp)는 expression과 뒤에 따라오는 for문, 그 뒤에 따라오는n개의 for나 if문을 포함한 brackets(대괄호[])로 구성되어있습니다.
listcomp의 구성 (for문과 if문의 배치)에 대해 예시를 통해 알아보겠습니다.
(listcomp의 구성(문법)을 말로써 설명하기 쉽지 않습니다.)
>>> vec = [-4, -2, 0, 2, 4] >>> # 요소 *2인 새로운 list 생성 >>> [x*2 for x in vec] [-8, -4, 0, 4, 8] >>> # 음수를 필터링합니다. >>> [x for x in vec if x >= 0] [0, 2, 4] >>> # 함수를 적용합니다. 아래에서 vec은 여전히 [-4, -2, 0, 2, 4]입니다. >>> [abs(x) for x in vec] [4, 2, 0, 2, 4] >>> # 각 요소에서 해당 객체의 method를 호출합니다. >>> # 아래 예제에서는 str.strip()함수를 호출하여 앞뒤 공백을 제거하도록 하였습니다. >>> freshfruit = [' banana', ' loganberry ', 'passion fruit '] >>> [weapon.strip() for weapon in freshfruit] ['banana', 'loganberry', 'passion fruit'] >>> # (숫자, 제곱결과) 형태의 튜플을 가지고 있는 리스트를 생성합니다. >>> [(x, x**2) for x in range(6)] [(0, 0), (1, 1), (2, 4), (3, 9), (4, 16), (5, 25)] >>> # 위와 같이 튜플을 안에 넣고 싶을 때, 반드시 튜플의 원소들은 괄호로 쌓여있어야합니다. >>> [x, x**2 for x in range(6)] File "<stdin>", line 1, in <module> [x, x**2 for x in range(6)] ^ SyntaxError: invalid syntax >>> # 차원을 줄입니다. >>> # 아래 listcomp는 다음과 같이 해석하면 쉽습니다. >>> # 1. vec에 있는 요소들을 elem으로 하나씩 꺼내오고, >>> # 2. 이 elem에 있는 요소들을 num으로 하나씩 꺼내온다. >>> # 3. 이 num을 expression으로하여 결과에 적용한다. >>> # 4. 즉, listcomp에서의 for문은 앞에서 뒤로 이해되는 것을 알 수 있습니다. >>> vec = [[1,2,3], [4,5,6], [7,8,9]] >>> [num for elem in vec for num in elem] [1, 2, 3, 4, 5, 6, 7, 8, 9] >>> # 1이 포함되지 않은 리스트를 대상으로 차원을 줄입니다. >>> [num for elem in vec if 1 not in elem for num in elem] # or [num for elem in vec for num in elem if 1 not in elem] : 동일한 효과를 냅니다. [4, 5, 6, 7, 8, 9] >>> # 1을 제외하고 차원을 줄입니다. >>> [num for elem in vec for num in elem if num!=1] # [num for elem in vec if num!=1 for num in elem ] : 에러가 발생합니다. num이 아직 정의되지 않았기 때문입니다. [2, 3, 4, 5, 6, 7, 8, 9]
listcomp의 expr, for, if의 구성에 대해 예제를 통해 정리해보겠습니다.
>>> [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
이 예시는 다음과 동일합니다.
>>> combs = [] >>> for x in [1,2,3]: ... for y in [3,1,4]: ... if x != y: ... combs.append((x, y)) ... >>> combs [(1, 3), (1, 4), (2, 3), (2, 1), (2, 4), (3, 1), (3, 4)]
이 둘의 공통점은 for문의 순서와 if문의 순서가 동일하다는 것입니다.
따라서, [(x, y) for x in [1,2,3] for y in [3,1,4] if x != y]은
각 for, if가 차례로 하위 코드블록을 이루며 구성되어있고, 가장 안쪽의 코드블록에 .append((x,y))가 있음을 확인할 수 있습니다.
[(x, y) for x in [1,2,3] for y in [3,1,4] if x != y] # ^1 ^2 ^3 ^4 # ^1 : 최하위(i=0) 코드블록 # ^2 : 최상위(i=n) 코드블록 # ^3 : i = n-1의 코드블록 # ^4 : i = n-1(=0+1)의 코드블록 #2~4까지 layer를 이루며 이전의 것의 하위 코드블록을 구성하며, 최하위 코드블록으로 ^1이 들어간다. cobs = [] for x in [1,2,3] : # 최상위 코드블록 for y in [3,1,4]: # 하위 1 코드블록 if x != y: # 하위 2 코드블록 combs.append((x,y)) # 최하위 코드블록
listcomp의 결과는 listcomp안의 for, if문들의 맥락안에서 연산된 expression의 결과들로 이루어진 새로운 리스트입니다.
리스트 표현식 + 문자열 포메팅 + join()등 다양한 기능을 합친 최종 보스이다.one -> five까지 5글자를 기준으로 c언어 배열로 초기화 할 수 있게하는 코드이다.이거를 왜 만들었냐하면,, 하나하나 다 입력하기 귀찮았기 때문..(물론 이 코드를 만드는데 더 많은 시간이 걸렸다. 하지만 나름 유익한 시간이었다)print('{'+',\n'.join(['{'+f"""'{"','".join([j for j in i])}'"""+'}' for i in [i+'-'*(5-len(i)) for i in ['ZERO','ONE','TWO','THREE','FOUR','FIVE']]])+'}')반응형'프로그래밍 > Python' 카테고리의 다른 글
Python - 달팽이 배열 설명(1) (1) 2021.06.08 Python - lambda expr에 대한 상세한 설명. (0) 2021.06.06 PyQt 폴더 선택 (0) 2021.05.29 파이썬 들여쓰기와 공백(indentation) (0) 2021.04.03 파이썬 format함수 사용법 (0) 2021.03.24