Python 주요 라이브러리 정리

쌈지몬·2022년 6월 30일
0
post-thumbnail

python은 1991년 귀도 반 로섬(Guido van Rossum)이라는 프로그래머에 의해 개발된 언어
다양한 라이브러리를 통해 높은 생산성을 가진 언어이다. 본 포스팅에서는 python에서 사용하는 기본적인 라이브러리와 이를 사용하는 방법을 정리함으로써 python을 좀 더 손쉽게 사용할 수 있는 방법을 제시하고자 한다.

표준 라이브러리

내장함수 : print(), input()과 같은 기본 입출력 기능부터 sorted()와 같은 정렬 기능을 포함하고 있는 기본 내장 라이브러리

itertools : 파이썬에서 반복되는 형태의 데이터를 처리하는 기능을 제공하는 라이브러리, 순열과 조합 라이브러리를 제공

heapq :(Heap) 기능을 제공하는 라이브러리. 우선순위 큐 기능을 구현하기 위해 사용한다.

collections :(deque), 카운터(Counter) 등의 유용한 자료구조를 포함하고 있는 라이브러리이다.

math : 필수적인 수학적 기능을 제공하는 라이브러리이다. 팩토리얼, 제곱근, 최대공약수, 삼각함수 관련 메서드부터 파이(pi)와 같은 상수를 포함하고 있다

bisect : 이진탐색을 위한 라이브러리

functools: 누적집계를 위한 reduce() 함수 사용 가능

Enumerate (loop 내 인덱스 사용)

for i, letter in enumerate(['A', 'B', 'C']):
	print(i, letter)

# 0 A
# 1 B
# 2 C

for i, letter in enumerate(['A', 'B', 'C'], start=1):
	print(i, letter)

# 1 A
# 2 B
# 3 C

수의 지수 표현

a = 1e9 // 1,000,000,000

a = 75.25e1 // 752.5

a = 3954e-3 // 3.954

반올림 rount 함수

round(123.456, 2) // 123.46

리스트 컴프리헨션

# 길이가 정해진 리스트 만들기
array = [0 for i in range(n)]

# 0부터 19까지의 수 중에서 홀수만 포함하는 리스트
array = [ i for i in range(20) if i % 2 == 1 ]

# 1부터 9까지의 수의 제곱 값을 포함하는 리스트
array = [ i**2 for i in range(10) ]

# 2차원 리스트 초기화
n = 3
m = 3
array = [[0] * m for _ in range(n)]
print(array)

리스트 관련 기타 메서드

변수.reverse() # 리스트의 순서 모두 뒤집음

변수.count(특정 값) # 리스트에서 특정 값을 가지는 데이터의 개수

변수.remove(특정 값) # 특정 값 가지는 원소 제거, 값이 여러 개면 하나만 제거

append() 함수는 O(1)에 실행되지만
insert() 함수는 O(N)에 실행된다 # 원소를 삽입한 뒤에, 리스트의 원소 위치를 조정해줘야 하기 때문

특정한 값의 원소를 모두 제거하려면?
a = [1, 2, 3, 4, 5]
remove_set = [1, 4]
result = [i for i in a if i not in remove_set] // [2, 3, 5]

#list Null Check?
if not list1:
    print("list1 is empty")

문자열 연산

a = "Hello"
b = "World"
print(a+b)
print(a + " " + b)

튜플

#튜플 자료형은 리스트와 거의 비슷하지만 다음과 같은 차이가 있다.
-튜플은 한 번 선언된 값을 변경할 수 없다.
-리스트는 대괄호를([])를 이용하지만, 튜플은 소괄호(())를 이용한다

튜플 자료형은 그래프 알고리즘을 구현할 때 자주 사용된다.

Dictionary 관련 함수

data = dict()
data['사과'] = 'apple'
data['바나나'] = 'banana'
data['코코넛'] = 'coconut'

# 키 데이터만 담은 리스트
key_list = data.keys()
# 값 데이터만 담은 리스트
value_list = data.values()

# 각 기에 따른 값을 하나씩 출력
for key in key_list:
	print(data[key])

Set

# Set은 다음과 같은 특징이 있다.
-중복을 허용하지 않는다.
-순서가 없다.

# Set 초기화 방법 1
data = set([1, 1, 2, 3, 4, 4, 5])

# Set 초기화 방법 2
data = {1, 1, 2, 3, 4, 4, 5}
# Set의 연산
a = set([1, 2, 3, 4, 5])
b = set([3, 4, 5, 6, 7])

print(a | b) # 합집합
print(a & b) # 교집합
print(a - b) # 차집합

{1, 2, 3, 4, 5, 6, 7}{3, 4, 5}{1, 2}

Set 관련 함수
# 하나의 원소을 추가할 때는 add()
data.add(4)

# 여러 개의 원소를 추가할 때는 update()
data.update([5, 6])

# 특정한 값을 갖는 원소 삭제
data.remove(3)

입력

입력의 개수가 많은 경우에는 input() 함수를 그대로 사용하지는 않는다.
파이썬의 기본 input() 함수는 동작 속도가 느려서 시간 초과로 오답 판정을 받을 수 있기 때문

이 경우 파이썬의 sys 라이브러리에 정의되어 있는 sys.stdin.readline() 함수를 이용한다.
다음과 같은 방식으로 사용하며 input() 함수와 같이 한 줄씩 입력받기 위함

import sys
sys.stdin.readline().rstrip()

sys 라이브러리를 사용할 때는 한 줄 입력을 받고 나서 rstrip() 함수를 꼭 호출해야 한다.

출력

문자열과 수를 함께 출력해야 되는 경우 단순히 + 연산자를 이용하여 문자열과 수를 더하면 오류가 발생한다.

# 오류 발생 코드
answer = 7
print("정답은 " + answer + "입니다.")

# 해결법
-str() 함수를 이용하여 출력하고자 하는 변수 데이터를 문자열로 바꾸어줌
-각 자료형을 콤마(,)를 기준으로 구분하여 출력

# f
-파이썬 3.6 이상의 버전부터 f-string 문법 사용 가능
-f-string은 문자열 앞에 접두사 'f'를 붙임으로써 사용할 수 있다

print(f"정답은 {answer}입니다")

itertools

permutations

# 리스트와 같은 iterable 객체에서 r개의 데이터를 뽑아 일렬로 나열하는 모든 경우(순열)을 계산해준다.
# permutations는 클래스이므로 객체 초기화 이후에는 리스트 자료형으로 변환하여 사용한다.

from itertools import permutations

data = ['A', 'B', 'C']
result = list(permutations(data, 3)) # 모든 순열 구하기

print(result)

[('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'),ㆍㆍㆍㆍㆍ('C', 'B', 'A')]

combinations

# combinations는 리스트와 같은 iterable 객체에서 r개의 데이터를 뽑아 순서를 고려하지 않고 나열하는 모든 경우(조합)을 계산한다.
# combinations는 클래스이므로 객체 초기화 이후에는 리스트 자료형으로 변환하여 사용한다.

from itertools import combinations

data = ['A', 'B', 'C']
result = list(combinations(data, 2)) # 2개를 뽑는 모든 조합 구하기

print(result)

[('A', 'B'), ('A', 'C'), ('B', 'C')]

product

# product는 permutations와 같이 리스트와 같은 iterable 객체에서 r개의 데이터를 뽑아
  일렬로 나열하는 모든 경우(순열)를 계산한다. 다만 원소를 중복하여 뽑는다 <- 중요!
# product 객체를 초가화 할 때는 데이터의 수를 repeat 속성값으로 넣어준다.
# product는 클래스이므로 객체 초기화 이후에는 리스트 자료형으로 변환하여 사용한다.

from itertools import product

data = [1, 2, 3]
result = list(product(data, repeat=2)) # 2개를 뽑는 모든 순열 구하기(중복 허용)

print(result)

[(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3, 2), (3, 3)]

combination_with_replacement

# combination_with_replacement는 combinations와 같이 리스트와 같은 iterable 객체에서
  r개의 데이터를 뽑아 순서를 고려하지 않고 나열하는 모든 경우(조합)을 계산한다.
# 다만 원소를 중복해서 뽑는다.
# combination_with_replacement는 클래스이므로 객체 초기화 이후에는 리스트 자료형으로 변환하여 사용한다.

from itertools import combinations_with_replacement

data = [1, 2, 3]
result = list(combinations_with_replacement(data, 2)) # 2개를 뽑는 모든 조합 구하기(중복 허용)

print(result)

[(1, 1), (1, 2), (1, 3), (2, 2), (2, 3), (3, 3)]

정리

permutations # 모든 순열 구하기
combinations # 2개를 뽑는 모든 조합 구하기
product # 2개를 뽑는 모든 순열 구하기(중복 허용)
combination_with_replacement # 2개를 뽑는 모든 조합 구하기(중복 허용)

heapq

# 파이썬의 힙은 최소 힙으로 구성되어 있으므로 단순히 원소를 힙에 전부 넣었다가 빼는 것만으로도
  시간 복잡도 O(NlogN)에 오름차순 정렬이 완료된다

# heapq.heappush() // 힙에 원소 삽입
# heapq.heappop() // 힙에서 원소 꺼냄
# heapq.heapify() // list를 heapq로 변환

# 파이썬에서는 최대 힙을 제공하지 않는다. 따라서 heapq 라이브러리를 이용하여 최대 힙을 구현해야 할 때는
  원소의 부호를 임시로 변경하는 방식을 사용한다. 삽입 전에 부호를 반대로 바꾸었다가, 꺼낸 뒤에 다시 원소의 부호를 바꾸면 된다.

import heapq

def heapsort(iterable):
    h = []
    result = []

    for value in iterable:
        heapq.heappush(h, -value)

    for _ in range(len(h)):
        result.append(-heapq.heappop(h))

    return result

result = heapsort([1, 3, 5, 7, 9, 2, 4, 6, 8, 0])
print(result)

[9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

bisect

# 파이썬에서는 이진 탐색을 쉽게 구현할 수 있도록 bisect 라이브러리를 제공한다.
# bisect 라이브러리는 '정렬된 배열'에서 특정한 원소를 찾아야 할 때 매우 효과적으로 사용된다.
# 이 두 메서드는 시간 복잡도 O(logN)에 동작한다.

bisect_left(a, x) #정렬된 순서를 유지하면서 리스트 a에 데이터 x를 삽입할 가장 왼쪽 인덱스를 찾는 메서드
bisect_right(a, x) #정렬된 순서를 유지하도록 리스트 a에 데이터 x를 삽입할 가장 오른쪽 인덱스를 찾는 메서드

# 예를 들어 정렬된 리스트 [1, 2, 4, 4, 8]이 있을 때, 새롭게 데이터 4를 삽입하려 한다.
list = [1, 2, 4, 4, 8]

bisect_left(list, 4) # 2 반환
bisect_right(list, 4) # 4 반환

# Binary Search
while l <= r: 
	mid = (l+r) // 2 
	if nums[mid] >= n: 
		result = mid 
		r = mid - 1 
	else: l = mid + 1

# 배열이 오름차순으로 정렬된 점을 이용해서, mid를 집고, mid 인덱스의 값이 작으면 l(left) 을 mid +1 로 올려 다음 후보 값을 높여주고, 아니면 r(right)을 mid -1 로 내려 다음 후보 값을 낮춰주는 방식입니다. 절반씩 후보를 줄여가기에 O(logN) 이 성립합니다.

/* Function */
def binary_search(arr, target):
    low, high = 0, len(arr) - 1
    while low <= high:
        mid = (low + high) // 2
        if arr[mid] > target:
            high = mid - 1
        if arr[mid] == target:
            return mid
        if arr[mid] < target:
            low = mid + 1
    return -1

collections

deque

# 보통 파이썬에서는 deque를 이용해 큐를 구현
# 리스트 자료형에서 앞쪽에 있는 원소를 삭제하거나 앞쪽에 새 원소를 삽입할 때의 시간복잡도는 O(N)이다.
  하지만 deque의 경우 O(1)
# deque에서는 리스트와 다르게 인덱싱, 슬라이싱 등의 기능을 사용할 수 없다.
  다만 연속적으로 나열된 데이터의 시작 부분이나 끝부분에 데이터를 삽입하거나 삭제할 때는 매우 효과적으로 사용될 수 있다
# deque는 스택이나 큐의 대용으로 사용될 수 있다.

popleft() # 첫 번째 원소 제거
pop() # 마지막 원소 제거
appendleft() # 첫 번째 인덱스에 원소 삽입
append() # 마지막 인덱스에 원소 삽입

# 따라서 deque를 queue로 이용할 때, 원소를 삽입할 때는 append()를 사용하고 삭제할 때에는 popleft()를 사용하면 된다.

Counter

def countLetters(word):
    counter = {}
    for letter in word:
        if letter not in counter:
            counter[letter] = 0
        counter[letter] += 1
    return counter

countLetters('hello world'))
# {'h': 1, 'e': 1, 'l': 3, 'o': 2, ' ': 1, 'w': 1, 'r': 1, 'd': 1}

# Counter는 등장 횟수를 세는 기능을 제공한다.
from collections import Counter

Counter('hello world')
# Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})

def find_max(word):
    counter = Counter(word)
    max_count = -1
    for letter in counter:
        if counter[letter] > max_count:
            max_count = counter[letter]
            max_letter = letter
    return max_letter, max_count

find_max('hello world') # ('l', 3)

# 데이터의 개수가 많은 순으로 정렬된 배열을 리턴
Counter('hello world').most_common() # [('l', 3), ('o', 2), ('h', 1), ('e', 1), (' ', 1), ('w', 1), ('r', 1), ('d', 1)]

Counter('hello world').most_common(1) # [('l', 3)]

math

import math

print(math.factorial(5)) # 5! 출력

print(math.sqrt(7) # 루트7 출력

print(math.gcd(21, 14)) # 21과 14의 최대 공약수 출력

print(math.lcm(21, 14)) # 21과 14의 최소 공배수 출력

print(math.pi) # 파이(pi) 출력

print (math.e) # 자연상수 e 출력

빠르게 입력받기

입력 데이터의 개수가 많은 문제에 input() 함수를 사용하면 동작 속도가 느려서 시간 초과로 오답 판정을 받을 수 있다. 입력 데이터가 많은 문제는 sys 라이브러리의 readline() 함수를 이용하면 시간 초과를 피할 수 있다.

import sys

input_data = sys.stdin.readline().rstrip()

print(input_data)

sys 라이브러리를 사용할 때는 한 줄 입력받고 나서 꼭 rstrip() 함수를 호출해야 한다.readline()으로 입력하면 입력 후 엔터가 줄 바꿈 기호로 입력되는데, 이 공백 문자를 제거하기 위해 사용.관행적으로 외워서 사용하자.

참고

https://ko.wikipedia.org/wiki/%ED%8C%8C%EC%9D%B4%EC%8D%AC
https://velog.io/@eazyan/%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EB%AC%B8%EB%B2%95-%EC%A0%95%EB%A6%AC-for-%EC%BD%94%EB%94%A9-%ED%85%8C%EC%8A%A4%ED%8A%B8

profile
What goes around comes around.

0개의 댓글