또 다른 반복문인 iteratools와 comprehension에 대해 정리합니다.
개요
- python의 주요 기능인 iteration모듈의 개념과 활용방법에 대한 내용을 정리합니다.
itertools 모듈 : 다양한 종류의 iterator(반복하는 것) 객체를 생성하는 함수들로 구성된 모듈
- product(), combination(), permutations() 3가지 함수로 구성되어 있다.
- 순회 가능한 여러개의 객체를 순서대로 순회하는 iterator를 생성하는 함수
1
2
3
|
for v1, v2, v3 in itertools.product(L1, L2, L3):
|
와 같은 식으로 작성한다.
이는 아래의 for 문과 동일한 구조이다.
1
2
3
4
5
6
7
|
for v1 in L1:
for v2 in L2:
for v3 in L3:
|
1
2
3
4
| # itertools.product 예제
count = 0
for a, b, c in itertools.product(range(5), range(5), range(5)):
print(a, b, c) # 각각의 for문이 도는 결과를 표시
|
0 0 0
0 0 1
0 0 2
0 0 3
0 0 4
0 1 0
0 1 1
0 1 2
0 1 3
...
4 3 3
4 3 4
4 4 0
4 4 1
4 4 2
4 4 3
4 4 4
1
2
3
4
5
| # 위 코드와 같은 방식으로 동작하는 코드
for a in range(5):
for b in range(5):
for c in range(5):
print(a, b, c)
|
0 0 0
0 0 1
0 0 2
0 0 3
0 0 4
0 1 0
0 1 1
0 1 2
...
4 4 1
4 4 2
4 4 3
4 4 4
즉, product() 함수는 nested for문의 깊이가 매우 깊을때 유용하게 사용된다.
1
2
| for a, b, c in zip(range(5), range(5), range(5)):
print(a, b, c)
|
0 0 0
1 1 1
2 2 2
3 3 3
4 4 4
- iterator 객체 p에서 크기 r의 가능한 모든 조합을 갖는 iterator를 생성하는 함수
1
2
3
| L = ['a', 'b', 'c', 'd']
for comb in itertools.combinations(L, 2): # L에서 2개로 이뤄진 가능한 모든 조합 뽑기
print(comb)
|
('a', 'b')
('a', 'c')
('a', 'd')
('b', 'c')
('b', 'd')
('c', 'd')
1
2
3
4
5
| # L에서 출력 가능한 모든 조합을 뽑으려면
for r in range(1, len(L) + 1): # L 전체 범위를 돌아야 하기 때문에 +1
for comb in itertools.combinations(L, r):
print(comb)
|
('a',)
('b',)
('c',)
('d',)
('a', 'b')
('a', 'c')
('a', 'd')
('b', 'c')
('b', 'd')
('c', 'd')
('a', 'b', 'c')
('a', 'b', 'd')
('a', 'c', 'd')
('b', 'c', 'd')
('a', 'b', 'c', 'd')
- iterator 객체 p에서 크기 r의 가능한 모든 순열을 갖는 iterator를 생성하는 함수
1
2
3
4
| # L에서 가능한 모든 순열 뽑기
for r in range(1, len(L)):
for comb in itertools.permutations(L, r):
print(comb)
|
('a',)
('b',)
('c',)
('d',)
('a', 'b')
('a', 'c')
('a', 'd')
('b', 'a')
('b', 'c')
('b', 'd')
('c', 'a')
('c', 'b')
('c', 'd')
('d', 'a')
('d', 'b')
('d', 'c')
('a', 'b', 'c')
('a', 'b', 'd')
('a', 'c', 'b')
('a', 'c', 'd')
('a', 'd', 'b')
('a', 'd', 'c')
('b', 'a', 'c')
('b', 'a', 'd')
('b', 'c', 'a')
('b', 'c', 'd')
('b', 'd', 'a')
('b', 'd', 'c')
('c', 'a', 'b')
('c', 'a', 'd')
('c', 'b', 'a')
('c', 'b', 'd')
('c', 'd', 'a')
('c', 'd', 'b')
('d', 'a', 'b')
('d', 'a', 'c')
('d', 'b', 'a')
('d', 'b', 'c')
('d', 'c', 'a')
('d', 'c', 'b')
List comprehension
1
2
3
|
[output for element in iterator if 조건]
|
의 형태로 작성된다.
e.g)
1
2
3
|
L = [x**2 for x in range(10) if x%2 ==0]
|
이는 아래의 for문과 동일한 의미이다.
1
2
3
4
5
6
7
8
9
|
L=[]
for x in range(10):
if x%2 == 0
L.append(x**2)
|
즉, 코드 작성시 여러줄이 필요한 것을 1줄로 깔끔하게 정리할 수 있다.
기본 comprehension
1
2
| L1 = [x for x in range(10)]
L1
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
1
2
3
4
5
6
7
| # 위의 comprehension을 다시 쓰면 다음과 같다.
# 실제로 결과도 같다.
L1 = []
for x in range(10):
L1.append(x)
L1
|
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
연산이 추가된 comprehension
1
2
| L2 = [x**2 for x in range(10)]
L2
|
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
1
2
3
4
5
6
7
| # 위의 comprehension을 다시 쓰면 다음과 같다.
# 실제로 결과도 같다.
L2 = []
for x in range(10):
L2.append(x**2)
L2
|
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
조건문이 붙은 comprehension
1
2
| L3 = [x**2 for x in range(10) if x%2 == 0]
L3
|
[0, 4, 16, 36, 64]
1
2
3
4
5
6
7
8
| # 위의 comprehension을 다시 쓰면 다음과 같다.
# 실제로 결과도 같다.
L3 = []
for x in range(10):
if x%2 == 0:
L3.append(x**2)
L3
|
[0, 4, 16, 36, 64]
1
2
3
4
5
| X = [1, 2, 3, 'a', 'b']
Y = [3, 1, 2, 'c', 4]
L4 = [x + y for x, y in itertools.product(X, Y) if type(x) == type(y) == int]
L4
|
[4, 2, 3, 5, 5, 3, 4, 6, 6, 4, 5, 7]
dictionary comprehension
- comprehension은 for문을 한 줄로 작성해 사전을 효과적으로 생성하는 방법이다.
1
2
3
|
{key:value for key, val in iterator if 조건}
|
의 형태로 작성된다.
e.g)
1
2
3
|
dic = {x:y**2 for x,y in zip(range(10), range(10)) if x%2 ==0}
|
이는 아래의 for문과 동일한 의미이다.
1
2
3
4
5
6
7
8
9
10
11
|
dic = dict()
for x,y in zip(range(10), range(10)):
if x%2 == 0:
dic[x] = y**2
|
x를 key로, y를 value로 하는 사전을 생성
즉, 코드 작성시 여러줄이 필요한 것을 1줄로 깔끔하게 정리할 수 있다.
기본 comprehension
1
2
| dic1 = {x:y for x, y in zip(range(10), range(10))}
dic1
|
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
1
2
3
4
5
6
7
| # 위의 comprehension을 다시 쓰면 다음과 같다.
# 실제로 결과도 같다.
dic1 = dict()
for x,y in zip(range(10),range(10)):
dic1[x] = y
dic1
|
{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}
dict의 NaN값을 items()를 활용해 채워넣기
-
이전에 정리한 바와 같이 dict 자료형은 items()함수를 이용하여 tuple형태로 key, value 순회 가능하다.
-
items() 사용법은 사전.items() 로 변형하여 tuple의 unpacking개념을 이용해 다수의 값을 한번에 대입하는 방식이다.
1
| dic = {1:'NaN', 2:2, 3:4, 4:'NaN'}
|
1
2
3
4
| # y! = NaN이면 그 값을 dict에 추가
dic2 = {x:y for x, y in dic.items() if y != 'NaN'}
dic2
|
{2: 2, 3: 4}
1
2
3
4
5
6
7
8
9
| # 위의 comprehension을 다시 쓰면 다음과 같다.
# 실제로 결과도 같다.
dic2 = dict() #빈 dict 정의
for x, y in dic.items(): # dict의 item을 loop
if y != 'NaN':
dic2[x] = y
dic2
|
{2: 2, 3: 4}
댓글남기기