[목차]
part6. Itertools / Collections 모듈
part6. Itertools / Collections 모듈
- 곱집합(Cartesian product) 구하기 - product
예시) 두 스트링 'ABCD', 'xy' 의 곱집합은 Ax Ay Bx By Cx Cy Dx Dy 입니다.
[for 문을 이용해 두 iterable의 원소를 하나씩 곱해가는 방법]
iterable1 = 'ABCD'
iterable2 = 'xy'
iterable3 = '1234'
for value1 in iterable1:
for value2 in iterable2:
for value3 in iterable3:
print(value1, value2, value3)
[파이썬의 itertools.product 이용하는 방법]
import itertools
iterable1 = 'ABCD'
iterable2 = 'xy'
iterable3 = '1234'
print(list(itertools.product(iterable1,iterable2,iterable3))
itertools.product(*iterables, repeat=1)
- 입력 iterables의 데카르곱(곱집합 혹은 카테시안 )
product('ABCD', 'xy') # --> Ax Ay Bx By Cx Cy Dx Dy
product(range(2), repeat=3) # --> 000 001 010 011 100 101 110 111
- 2차원 리스트를 1차원 리스트로 만들기
[나의 코드]
# + 연산자 사용
def solution(mylist):
answer = []
for i in mylist:
answer += i
return answer
# 이중 for문
def solution(mylist):
answer = []
for i in mylist:
for j in i:
answer.append(j)
return answer
[파이썬다운 코드 - for문 사용x]
my_list = [[1, 2], [3, 4], [5, 6]]
# 방법 1 - sum 함수
answer = sum(my_list, [])
# 방법 2 - itertools.chain
import itertools
list(itertools.chain.from_iterable(my_list))
# 방법 3 - itertools와 unpacking
import itertools
list(itertools.chain(*my_list))
# 방법 4 - list comprehension 이용
[element for array in my_list for element in array]
# 방법 5 - reduce 함수 이용 1
from functools import reduce
list(reduce(lambda x, y: x+y, my_list))
# 방법 6 - reduce 함수 이용 2
from functools import reduce
import operator
list(reduce(operator.add, my_list))
# 방법 7 - numpy 라이브러리의 flatten 이용
# 각 원소의 길이가 동일한 경우에만 사용 가능
import numpy as np
np.array(my_list).flatten().tolist()
<이중 리스트를 flatten하게 만드는 함수>
1. sum(iterable, start=0) : 내장함수
start 값으로 []을 넣어주면 리스트 덧셈이라는 의미이다.
sum(mylist)는 0+[1,2]+[3,4]+[5,6] 이므로 int와 list 의 덧셈은 TypeError가 발생한다.
sum(mylist, [])는 [] + [1,2] + [1,2,3] 이므로 리스트끼리의 덧셈이 된다.
2. chain.from_iterable(iterable) : import itertools
인자로 받은 iterator의 element들을 조회하면서 넘겨준다.
3. chain(*iterables) : import itertools
인자로 받은 iterator들의 원소를 연결해 반환한다.
인자들을 엮어주는 것이므로 2차원 리스트를 1차원 리스트로 얻고 싶다면 인자에 *(asterisk)을 붙여주어 전달해야한다.
4. list comprehension
[element for array in my_list for element in array]
1) for array in my_list 구문이 먼저 해석되어 my_list의 element들이 각각 array에 들어가고2) element for element in array 구문이 해석되어 각각의 array에 들어있는 element들이 element로 조회되고 최종적으로 element로 이루어진 1차원 리스트가 생성된다.
5. reduce(집계 함수, 순회 가능한 데이터[, 초기값]) : import fuctools
순회가능한 데이터 내 각 요소를 연산한 뒤 이전 연산 결과들과 누적해서 반환해 준다. 집계 함수는 두 개의 인자를 받아야한다. 첫번째 인자는 함수 실행의 시작부터 끝까지 계속해서 재사용되는 값인 누적자이고,두번째 인자는 루프를 돌면서 계속해서 바뀌는 현재값이다.
6. add(x, y) : import operator
reduce 함수의 인자에 lambda 함수가 아닌 add를 사용할 수 있다.
7. array().flatten().tolist() : import numpy
array() - 2차원 리스트를 ndarray 객체로 바꾸어 flatten() - 2차원 array를 1차원 array로 변환한 후 tolist() - 다시 list형으로 반환
참고: https://blog.winterjung.dev/2017/04/21/list-of-lists-to-flatten
- 순열과 조합 - combinations, permutations
import itertools
def solution(mylist):
return sorted(list(map(list,itertools.permutations(mylist))))
순열 - itertools.permutations(n, r)
조합 - itertools.combinations(n, r)
- 가장 많이 등장하는 알파벳 찾기 - Counter
[나의 코드]
my_str = input().strip()
alp = [0 for i in range(26)]
for i in my_str:
alp[ord(i)-97] += 1
l = list(filter(lambda x:alp[x]==max(alp), range(len(alp))))
result = ''
for i in l:
result+=chr(i+97)
print(result)
[collections.Counter 클래스 사용한 코드]
from collections import Counter
my_str = input().strip()
max_count = max(Counter(my_str).values())
print(''.join(sorted([k for k,v in Counter(my_str).items() if v == max_count])))
collections.Counter()
- dictionary를 확장하고 있기 때문에, dict에서 제공하는 api를 그대로 사용할 수 있다.
import collections
my_str = "bbaa"
answer = collections.Counter(my_str)
print(answer)
# Counter({'b':2,'a':2})
part7. 기타
- for 문과 if 문을 한번에 - List comprehension의 if 문
[나의 코드] = [for 문과 if 문을 한 번에 처리하는 코드]
answer = [i**2 for i in mylist if i%2 == 0]
* list comprehension
대괄호 사이에 for문, if 문을 사용하여 간결하게 list를 만들 수 있게 해준다.
1. 기본 구조: 표현식 + for 문
result = [표현식 for 변수 in 리스트]
2. 표현식 + for 문 + 조건문
result = [표현식 for 변수 in 리스트 조건문]
3. 조건문 + for 문
result = [조건문 for 변수 in 리스트]
4. 중첩 for 문
result = [조건문 for 변수1 in 리스트1 for 변수2 in 리스트2 ...]
5. 중첩 list comprehension
참고 블로그: List Comprehension 문법 정리
- flag OR for-else
[나의 코드]
numbers = [int(input()) for _ in range(5)]
l = []
result = 1
for i in numbers:
result *= i
l.append(result)
flag = 1
for j in l:
if (j ** 0.5) == int(j ** 0.5):
print('found')
flag = 0
break
if(flag == 1):
print('not found')
[for-else 문 사용한 코드]
import math
numbers = [int(input()) for _ in range(5)]
multiplied = 1
for number in numbers:
multiplied *= number
if math.sqrt(multiplied) == int(math.sqrt(multiplied)):
print('found')
break
else:
print('not found')
for-else 문
for 문이 break 등으로 중간에 빠져나오지 않고 끝까지 실행됐을 경우 else 문이 실행된다.
- 두 변수의 값 바꾸기 - swap
예) a = 3, b = 'abc' 를 a = 'abc', b = 3 으로 바꾸기
[나의 코드]
a = 3
b = 'abc'
tmp = a
a = b
b = tmp
[파이썬다운 코드]
a = 3
b = 'abc'
a,b = b,a
- 이진 탐색하기 - binary search
이진탐색 - 오름차순으로 정렬된 리스트에서 특정한 값의 위치를 찾는 알고리즘
[반복문으로 이진 탐색 알고리즘 구현]
def bisect(a, x, lo=0, hi=None):
if lo < 0:
raise ValueError('lo must be non-negative')
if hi is None:
hi = len(a)
while lo < hi:
mid = (lo+hi) // 2
if a[mid] < x:
lo = mid + 1
else:
hi = mid
return lo
mylist = [1,2,3,7,9,11,33]
print(bisect(mylist, 3))
[bisect.bisect 메소드 사용]
import bisect
mylist = [1,2,3,7,9,11,33]
print(bisect.bisect(mylist,3))
- 클래스 인스턴스 출력하기 - class 의 자동 string casting
예) 2차원 평면 위의 점을 나타내는 Coord 클래스의 인스턴스를 (x값, y값) 으로 출력하기[클래스 바깥에 출력 함수를 만들거나, print 문 안에서 format 지정]
class Coord(object):
def __init__(self, x, y):
self.x , self.y = x, y
point = Coord(1, 2)
print('({}, {})'.format(point.x, point.y))
#또는
def print_coord(coord):
print('({},{})'.format(coord.x, coord.y))
print_coord(point)
[__str__ 메소드를 사용해 class 내부에서 출력 format을 지정]
class Coord(object):
def __init__ (self, x, y):
self.x , self.y = x, y
def __str__ (self):
return '({}, {})'.format(self.x, self.y)
print = Coord(1, 2)
- 가장 큰 수, inf
[임의의 큰 수(99999)를 할당]
min_val = 99999
[inf는 어떤 숫자와 비교해도 무조건 크다고 판정된다.]
min_val = float('inf')
min_val > 100000000 #True
max_val = float('-inf')
- 파일 입출력 간단하게 하기
예) 'myfile.txt'라는 이름의 파일을 읽는 코드를 짜보세요.
[EOF를 만날 때까지, 파일 읽기를 반복]
f = open('myfile.txt', r)
while True:
line = f.readline()
if not line:
break
raw = line.split()
print(raw)
f.close()
[with - as 구문을 이용]
1. 파일을 close 하지 않아도 된다: with - as 블록이 종료되면 자동으로 close 된다.
2. readlines 가 EOF까지만 읽으므로, while 문 안에서 EOF를 체크할 필요가 없다.
with open('myfile.txt') as file:
for line in file.readlines():
print(line.strip().split('\t'))
'Python' 카테고리의 다른 글
파이썬을 파이썬 답게 Part.2~ 5 (0) | 2023.02.28 |
---|