알고리즘 문제에서 자주 쓰이는 함수들을 모아서 정리해봤습니다.
실전에서 많이 쓰이는 함수만 모으고 나머지는 과감히 삭제했습니다.
주기적으로 업데이트 해나갈 예정입니다.
최근수정일: 2023-10-28
lst = [1,2,3,4,5]
first_index, *rest, last_index = lst # rest=[2,3,4]
print(*lst) # 1 2 3 4 5
a, b, c = [1, 2, 3]
d = a, b, c # d = (1, 2, 3)
(변수를 활용해 만들 값) for (변수 명) in (순회할 수 있는 값)
if의 쓰임새:
앞쪽에 붙는 if는 삼항연산자의 if 이다. 즉 {참일때값} if {조건} else {거짓일때 값}
뒤쪽에 붙는 if는 값을 넣을지 뺄지 결정하는 조건이다.
[i for i in tmp if i % 3 == 0] # tmp에서 3의 배수만 넣기
[(j, i) for i, j in list_of_tuple] # 튜플을 뒤집기
[i if i <= 15 else 15 for i in tmp] # 15가 넘어가는값은 15로 바꾸기
[(i, j) for i in x, for j in y] # x,y에서 하나씩 뽑아서 가능한 모든 조합을 저장하기
{b:c for b, c in zip(['a', 'b', 'c'], [1,2,3]) } # 딕셔너리도 가능
# 이중 list comprehension (비권장)
matrix = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
flat = [x for row in matrix for x in row]
# flat == [1, 2, 3, 4, 5, 6, 7, 8, 9]
for j in range(N):
if sample[i][j] != 1:
break
else:
# 반복문을 break로 탈출하지 않으면 진입하는 구간
참고: https://ooyoung.tistory.com/75
max({iterable}, [,default,key])
# "1" < "a" < "ㄱ"
# 'AAB' > 'AAAB'
# default: iterable 객체가 비어있을경우 반환할 값. 없으면 비어있을때 에러남
min(-5, 3, 0, 3, -5, key=abs) # 절댓값이 가장 작은 값
max(*a,*b,*c) # a,b,c 배열에서 가장 큰 원소
s.count(찾을 값) # 문자열 내에서 찾을 값의 개수 반환
s.find(찾을값, 시작, 종료) # 값이 처음으로 나타나는 위치 반환.
# 값이 없을경우 -1 반환.
s.rfind(찾을값, 시작, 종료) # 반대로 찾기
s.split({delim})
# split()과 split(' ')는 다르다. split()은 공백이 연속되여도 하나로봄.
s.splitlines() # \n 기준으로 나눔
{delim}.join(lst_or_set)
s.upper()
s.lower()
s.isupper() # 문자열 전체가 대문자인지 판정함
s.islower() # 문자열 잔체가 소문자인지 판정함
s.swapcase() # 대소문자 반대로 만들어 리턴
s.title() # 각 단어의 앞글자만 대문자로 바꾸어 리턴.
# 단어를 나누는 기준은 '문자가 아닌 모든 글자'임
#'3people' -> '3People'
string.capwords(str, ' ') # 각 단어를 공백으로 나눈다음 앞글자를 대문자로 바꿔서 리턴.
s.istitle()
s.capitalize() # 문자열의 맨 앞글자만 대문자로 바꾸어 리턴함
s.replace(기존값, 변경할값, 변경횟수)
s.maketrans("tps", "123") # t->1, p->2, s->3 로 치환
s.strip(제거할값)
s.lstrip(제거할값) # 왼쪽에서부터 특정값 제거
s.rstrip(제거할값)
s.zfill({integer}) # 문자열의 길이가 정수가 될때까지 왼쪽에 0을 채움
s.rjust({integer}, 원하는 값) # 길이가 정수가 될때까지 왼쪽에 원하는값을 채움
s.ljust({integer}, 원하는 값) # 오른쪽에 원하는 값을 채움
s.center({integer}, 원하는 값) # 양옆에 원하는 값을 채움. 홀수면 왼쪽에 하나 더채움
s.startswith("특정 문자열") # 특정 문자열이 s 보다 길어도 에러안남
s.endswith("특정 문자열")
s.isspace() # 모두 공백인가
s.isalpha() # 모두 알파벳인가 (한글 포함)
s.isalnum() # 모두 알파벳이나 숫자인가
s.isdigit() # 모두 숫자인가
print(a, end=" ")
a=12
f'{a+2}asdf' # 14asdf
0~9의 아스키코드: 48~57
A~Z의 아스키코드: 65~90
a~z의 아스키코드: 97~122
대문자와 소문자의 차이: 32
ord(s) # 아스키코드로 변환
chr(i) # 문자로 변환
참고: https://blog.naver.com/jjys9047/221996234577
import string
string.ascii_lowercase # a~z까지 소문자가 있는 문자열
string.ascii_uppercase
string.digits # 0~9
string.hexdigits # 0~9a~fA~F
# 1. 매칭시킬 패턴을 생성
import re
p = r'ab*'
# 2. 문자열 검색
m = re.match(p, str1) # 문자열의 처음부터 매치되는지 조사
m = re.search(p, str1) # 문자열 전체를 검색하여 매치되는지 조사
m = re.findall(p, str1) # 매치되는 모든 문자열을 리스트로 리턴
# 3. match객체 메서드 사용
m.group() # 매치된 문자열을 리턴
m.start() # 매치 시작위치 리턴
m.end() # 매치 끝위치 리턴
# re.match('abc', 'abc').end() == 3
m.span() # 매치 (시작, 끝) 리턴
[abc]
는 ‘a, b, c 중 한 개의 문자와 매치’를 뜻함
[a-zA-Z] : 모든 알파벳
[0-9] : 모든 숫자
[ ] : 스페이스바
[aa] : 'a'를 찾음
\d : 숫자
\s : 화이트스페이스 (스페이스바, 탭, 줄바꿈등)
\w : 문자,숫자
\d, \s, \w 등을 대문자로 쓰면 반대로 매치된다.
\n
을 제외한 모든 문자.
a.b
위 정규식의 의미는
'a + 모든문자 한개 + b'
a*b
a가 0부터 무한히 반복 가능하다
a+b
a가 1부터 무한히 반복 가능하다
a{2}b
a가 반드시 2번 반복
a{2,4}b
a가 2~4번(4 포함) 반복
a{2,}
a{,3}
a?b
a가 0개거나 1개
시작: ^
끝: $
pattern = r"^abc$"
match1 = re.search(pattern, "abc") # 일치
match2 = re.search(pattern, "abcd") # 불일치
결과가 소모되지 않게함.
X(?=Y) # Positive lookahead : X is followed by Y
X(?!Y) # Negative lookahead
(?<=Y)X # Positive lookbehind : X is after Y
(?<!Y)X # Negative lookbehind
# 2글자가 연속적으로 글자인지 체크
p = r'(?=([a-z]{2}))'
re.findall(p, 'franc2e') # ['fr', 'ra', 'an', 'nc']
# 절대값
abs()
# 몫과 나머지를 받아 튜플 형태로 리턴
divmod(8,3) # (2,2)
# 16진수로 리턴
hex(100) # 0x64
hex(0b10101) # 0x15
# 제곱하기
pow(2,3) # 2^3
2**3
# 숫자를 이진수 형태의 문자열로 표현
bin(4) # '0b100'
# 이진수로 정수를 나타내는데 필요한 비트수 리턴
(0b000100).bit_length() # 3 (오른쪽 100 표현하는 3비트 필요)
# 숫자 연속비교
1 < x < 5
import math
math.factorial(x)
math.sqrt(x) # 루트값
math.gcd(a,b) # 최대공약수
math.lcm(a,b) # 최소공배수; 3.9에서 추가됨
math.pi
math.e
math.ceil(x) # 올림
math.floor(x)
math.round(x)
int(string, base)
코드 작성 필요
import string
digit = string.hexdigits
def convert(num, base):
q, r = divmod(num, base)
if q:
return convert(q, base) + digit[r]
else:
return digit[r]
lst = []
lst.insert(요소, 위치) # 특정 위치에 요소 삽입
lst.append(요소) # 끝에 요소 하나 삽입. O(1)
lst.count(요소) # 요소의 개수를 셈
lst.clear() # 요소 모두 삭제
del lst[1] # 특정 위치의 요소 삭제. O(n)
lst.remove(요소) # 특정 값을가진 첫번째 요소 삭제
lst.pop() # 마지막 요소 리턴후 삭제. O(1)
lst.pop(0) # 첫번째 요소 리턴후 삭제. O(n)
lst.extend(병합할리스트) # 리스트 병합
# lst1 + 병합할리스트 와 같으나 더 빠름
# O(병합할 리스트의 원소수)
lst.index(요소) # 요소에 해당하는 첫번째 위치 검색
# 없을경우 에러를 리턴함
lst.sort() # 내부적으로 정렬함. O(nlogn)
lst.reverse() # 리스트를 역순으로 치환
list(reversed(lst)) # 리스트 역순을 리턴
# 리스트 반복하기
[0] * 5 = [0,0,0,0,0]
# 참고로 lst = [[0,0,0]] * 3 이렇게 리스트를 초기화할 경우, 3개의 [0,0,0]은 모두 같은 객체로 인식이 된다. 즉 lst[0][0] = 2를 하면 lst는 [[2,0,0],[2,0,0],[2,0,0]] 이 된다.
# 따라서 올바른 방법은 [[0]*3 for _ in range(3)] 이다.
lst[i:j] # 리스트 슬라이싱. O(j-i)
# 인덱스가 없는곳까지 넘어가도 에러없음
# 빈 2차원 리스트 생성하기
arr = [[] for _ in range(n)] # [[], [], [] ...]
# 2차원 리스트 1차원으로 합치기
# 속도는 느림
a = [[1,2,3], [4,5]]
sum(a, []) # [1,2,3,4,5]
참고: https://dogrushdev.tistory.com/134
all(lst) # 모두 참이면 True, 거짓이 하나라도 있으면 False
any() # 하나라도 참이면 True
enumerate() # 순서가 있는 자료형을 입력인수로 받아 index, 값을 리턴
for i, name in enumerate(['a','b','c','d'])
filter() # 첫번째 인수로 함수의 이름을 넣고 두번째 인수에 iterable을 넣으면 하나씩 함수에 집어넣어 True인것은 그대로 iterable에 넣어서 돌려줌.
non_capitalized = list(filter(str.upper, ["a", "b"])) #[a, b]
map() # 첫번째 인수로 함수의 이름을 넣고 두번째 인수에 이터러블을 넣으면 하나씩 함수에 집어넣어 변화된 값을 그대로 객체형태로 돌려줌.
capitalized = list(map(str.upper, ["a", "b"])) # [A, B]
sorted() # 정렬하여 리스트를 리턴
sorted("python") # ['h','n','o','p','t','y']
sorted({1,2,3}) # [1,2,3]
sorted(a, reverse=True) # 거꾸로 정렬
sorted(a, key=lambda x:(x[0], -x[1])) # 정렬 기준을 직접 주기
zip() # 같은 갯수를 가진 여러 iterable의 요소를 같은 인덱스끼리 묶어 리턴
# zip 객체가 리턴되므로 list로 변환할 필요가 있음
list(zip(['a','b','c'],['A','B','C'])) # [('a', 'A'), ('b', 'B'), ('c', 'C')]
s1 = set([1, 2, 3, 4, 5, 6])
# set of tuple 가능, set of list, set of set 불가, set of frozenset가능
s1 = set(frozenset([1,2,3]), frozenset([3,4,5]))
# 교집합
s1 & s2
{4,5,6}
# 합집합
s1 | s2
# 차집합
s1 - s2
# 값 추가
s1.add(4)
# 값 여러개 추가
s1.update([4,5,6])
# 특정값 제거
s1.discard(2)
# remove와 다르게 값이 없어도 에러가 나지않음
# 집합이 속하는지 여부
{1,2}.issubset({1,2,3}) # True
{1,2,3}.issuperset({1,2}) # True
# 두 집합간 교집합이 없는지 여부
{1,2,3}.isdisjoint({4,5}) # True
# 원소 내보내기 (순서가 보장되지 않음)
s1.pop()
d = {1:'a'}
list(d) # 모든 키 반환
len(d) # 모든 아이템의 개수 반환
d.keys()
d.values()
d.items() # 키값쌍들
dict.fromkeys(seq, value) # seq를 키로하여 새로운 딕셔너리 생성. 기본 value는 None.
d.pop(key[, default]) # key에 해당하는 아이템을 삭제하고 value를 반환. 원소가 없으면 default 반환.
d.popitem() # 아이템을 pop하고 (key, value) 쌍을 반환.
d.setdefault(key[, default]) # key가 딕셔너리에 있으면 그 value을 반환하고, 없으면 key에 default에 해당하는 값을 넣고 default를 반환함.
d.update({otherdict}) # 다른 딕셔너리의 키값쌍을 덮어씌움
d | otherdict # 두 dict를 합치고 반환. otherdict이 우선권을 가짐
사전에 존재하지 않는 키라면 디폴트값을 넣어서 생성해준다.
from collections import defaultdict
mp = defaultdict(list, zip(a,b) )
mp["aa"].append("bb")
mp["aa"].append("cc")
참고: https://uni2237.tistory.com/56
PriorityQueue보다 빠른 힙
import heapq
arr = [3,2,1]
heapq.heapify(arr) # 리스트를 최소힙으로 바꿈. O(n)
# arr[0]에 가장 작은 원소가 있다.
heapq.heappush(arr, value) # 원소 삽입
# 최대 힙을 만드려면 부호를 반대로 해서 넣는다.
a = heapq.heappop(arr) # 가장 작은 원소 꺼냄
정렬된 리스트에서 값을 삽입할 인덱스를 알아냄
from bisect import bisect_left, bisect_right
left = bisect_left(arr, val) # 정렬된 리스트에 데이터를 삽입할 가장 왼쪽 인덱스
right = bisect_right(arr, val) # 정렬된 리스트에 데이터를 삽입할 가장 오른쪽 인덱스
bisect_right - bisect_left # 값이 특정 범위에 속하는 원소의 개수를 구함
앞뒤로 빠르게 입출력이 가능한 자료구조. 큐 구현할때 사용
from collections import deque
deq = deque(iterable[,maxlen]) # maxlen을 넘으면 자동으로 popleft()를 함
deq.append(5)
deq.appendleft(1)
deq.copy() # 얕은복사본을 만듬
deq.extend(iterable) # 데크 오른쪽에 붙여넣음
deq.extendleft(iterable)
deq.insert(i, x) # i위치에 x를 삽입
deq.pop()
deq.popleft()
deq.remove(value) # 첫번째 value를 제거함
iterable에서 내부원소가 몇번씩 등장했는지 알려줌
from collections import Counter
counter = Counter([1,2,3,4,1,1])
counter[1] # 3
counter[5] # 0
# 개수가 많은 원소순으로 리턴하기
counter.most_common()
Counter('hello world').most_common(2) # 상위 2개 리턴. [('l', 3), ('o', 2)]
from itertools import *
list(combinations(arr, 2)) # arr에서 2개씩 꺼내는 조합 튜플 형식으로 리턴
# 예: [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]
list(permutations(arr, 2)) # 2개씩 꺼내는 순열
list(product(arr, repeat=2)) # repeat 개수만큼 똑같은걸 여러번 꺼낼수있는 중복순열
list(product(*[[1,2,3],[4,5],[6]])) # 각 리스트에서 하나씩 꺼내기
# [(1, 4, 6), (1, 5, 6), (2, 4, 6), (2, 5, 6), (3, 4, 6), (3, 5, 6)]
list(combinations_with_replacement(arr,2)) # 2개씩 꺼내는 중복조합
순열 : n Pr = n! / (n-r)! =
math.factorial(n) // math.factorial(n-r)
조합 : nCr = n! / (n-r)!r! =
math.factorial(n) // math.factorial(n-r) // math.factorial(r)
중복순열 : n𝛑r = nr =
n**r
중복조합: nHr = n+r-1Cr =
math.factorial(n+r-1) // math.factorial(n-1) // math.factorial(r)
참고: https://dojang.io/mod/page/view.php?id=2461
참조 < 제곱 < 사칙연산 < 비트연산 < 비교 < 논리연산 < 할당
# 문자열을 실행
eval({실행할 문자열})
# 재귀호출 제한풀기
import sys
sys.setrecursionlimit(10**6)
# 빠르게 입력받기
import sys
input = sys.stdin.readline