Get started
파이썬을 파이썬답게!
파이썬에 사용을 조금 더 부드럽게 하기 위한 Cheat sheet
지속 업데이트 할 예정 (2022.07.10 ~ )
가독성이나 팀 코드 스타일에 따라 다를 수 있으니 유연하게 대처하고 사용하는 걸로 하자
아래의 코드는 pythonic하지 않음!!
def solution(li):
answer = []
for i in li:
answer.append(len(i))
return answer
이것이 파이썬이다.
(한줄 코딩이 파이써닉..?)
def solution(li):
return list(map(len, li))
Unpacking
파이썬에서는 Asterisk(*) 를 매우 다양하게 사용하고 있다
곱셈 연산, 가변 인자 사용 등 여러 상황에서 사용하지만 여기서는 packing & unpacking의 예를 보겠다
list의 값들을 unpacking하여 풀어서 사용 가능
li = [1, 3, 5, 7, 9]
print(li) # [1, 3, 5, 7, 9]
print(*li) # 1 3 5 7 9
가변 인자로 넘겨줄 때 아주 간편하게 사용이 가능하다
from functools import reduce
li = [3, 6, 9, 12, 15]
def sum(*numbers):
s = reduce(lambda x, y: x + y, numbers)
return s
sum(*li) # 45
물론 dictionary도 가능 list, tuple과는 달리 **를 사용함
def dict_unpack(A, B):
return A*B
C = {'A':2, 'B':2 }
dict_unpack(**C) # 4
음 간단하군...
cf) Dictionary review
user = {
"name" : "jason",
"email" : "junsu.pbear@kakao.com",
"password" : None
}
def personal_info(**kwargs):
for kw, arg in kwargs.items():
print(kw, ': ', arg, sep='')
print(*user) # name email password
personal_info(**user) # name: jason
# email: junsu.pbear@kakao.com
# password: None
단일로 unpacking을 할 경우에는 *var, = [...] 로 적어준다
*var,로 받는 인자의 경우에 일단 unpacking 된 다음에 변수에 할당되는 값들은 제외한 후 다시 packing
numbers = [1, 2, 3, 4, 5, 6]
*a, = numbers
# a = [1, 2, 3, 4, 5, 6]
*a, b = numbers
# a = [1, 2, 3, 4, 5]
# b = 6
a, *b, = numbers
# a = 1
# b = [2, 3, 4, 5, 6]
a, *b, c = numbers
# a = 1
# b = [2, 3, 4, 5]
# c = 6
몫과 나머지
몫과 나머지를 구해야 하는 상황
a,b를 input으로 공백으로 구분되게 받는다고 하면 기본 연산자를 사용하게 되면 아래와 같음
a, b = map(int, input().strip().split(' '))
print(a // b, end = ' ')
print(a % b, end = ' ')
But in Python...
a, b = map(int, input().strip().split(' '))
print(*divmod(a, b)) # unpacking
divmod() 함수를 사용하여 한 번에 구할 수 있다
그러나 모든 상황에서 사용하는 것이 좋은 방법은 아님
퍼포먼스의 경우에 작은 수를 다루게 되면 오히려 느릴 수 있음
적절한 상황에서 사용할 수 있도록 하자
진법 변환
5진법으로 적혀있는 문자열 10진법으로 변환하기
num = '3212'
base = 5
answer = 0
for idx, number in enumerate(num[::-1]):
answer += int(number) * (base ** idx)
But in Python...
num = '3212' # 문자열이여야 함
base = 5 # 몇 진법인가
answer = int(num, base) # 432
10진법으로의 변환은 아주 자유로움
그렇다면 10진수에서의 변환은...?
# 결과값은 모두 string
print(bin(10)) #0b1010
print(oct(10)) #0o12
print(hex(10)) #0xa
# 앞에 2개의 값은 진법을 나타냄
print(hex(10)[2:]) #a
이건 그냥 만들어서 쓰자...
import string
tmp = string.digits+string.ascii_lowercase
def convert(num, base) :
q, r = divmod(num, base)
if q == 0 :
return tmp[r]
else :
return convert(q, base) + tmp[r]
sorted()
파이썬 기본 내장함수인 sort() 도 존재하지만 이 함수는 원본의 순서를 바꿈
list1 = [3, 2, 5, 1]
list2 = [i for i in list1] # 또는 copy.deepcopy를 사용
list2.sort()
요렇게 하면..?sorted(iterable, /, *, key=None, reverse=False)
list1 = [3, 2, 5, 1]
list2 = sorted(list1)
새롭게 복사된 list에 정렬이 된다
여러개의 비교 요소도 tuple로 처리하여 우선 순위를 정해줄 수 있다
a = [(1, 2), (5, 1), (0, 1), (5, 2), (3, 0)]
e = sorted(a, key = lambda x : (x[0], -x[1])) # 마이너스를 붙이면 현재와 반대 정렬
# [(0, 1), (1, 2), (3, 0), (5, 2), (5, 1)]
zip()
zip(*iterables) 각 iterables의 요소들을 모은 iterator
mylist = [1, 2, 3]
new_list = [40, 50, 60]
for i in zip(mylist, new_list):
print (i)
# (1, 40)
# (2, 50)
# (3, 60) # tuple을 return
dicitonary도 생성 가능!
animals = ['cat', 'dog', 'lion']
sounds = ['meow', 'woof', 'roar']
answer = dict(zip(animals, sounds))
print(answer) # {'cat': 'meow', 'dog': 'woof', 'lion': 'roar'}
2차원 배열 전치 행렬로 뒤집기도 가능!
mylist = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
new_list = list(map(list, zip(*mylist)))
index를 사용하지 않고 각 원소에 접근할 수 있다
But 서로 길이가 다른 iterator가 들어오게 되면 짧은 쪽까지만 iteration이 이뤄진다
def solution(mylist):
answer = []
for number1, number2 in zip(mylist, mylist[1:]):
answer.append(abs(number1 - number2))
return answer
if __name__ == '__main__':
mylist = [83, 48, 13, 4, 71, 11]
print(solution(mylist))
길이가 긴 쪽을 조용히 잘라내는 것이 싫을 경우에는..?itertools.zip_longest(*iterables, fillvalue=None)
from itertools import zip_longest
x = [1, 2, 3]
y = [4, 5, 6,7]
zipped = zip_longest(x, y)
print(list(zipped)) # [(1, 4), (2, 5), (3, 6), (None, 7)]
zipped = zip_longest(x, y, fillvalue=0)
print(list(zipped)) # [(1, 4), (2, 5), (3, 6), (0, 7)]
map()
iterator의 요소를 지정된 함수로 처리해주는 함수
t1 = (3.14, 3.5, 22.6)
t2 = list(map(int, t1)) # [3, 3, 22]
여러가지로 활용이 가능해 보이니까 조금 더 신박한 사용 예 찾아보기
join()
join, split, strip, ljust, replace 등등 문자열 조작하는 함수는 자주 사용하니까...
split(sep=None, maxsplit=-1)
join(__iterable: Iterable[str]) -> str
li = ["6","6","6","6","6","6","6","6"]
s = ''.join(li) # 66666666
s2 = ' '.join(li) # 6 6 6 6 6 6 6 6
l = s.split() # ['66666666']
l2 = s2.split # ['6', '6', '6', '6', '6', '6', '6', '6']
product()
파이썬은 iterable한 객체가 너무 많음itertools.product()
곱집합을 잘 만들어내는 것 가능!
from itertools import product
iterable1 = 'ABCD'
iterable2 = 'xy'
cartesian = list(map(''.join, list(product(iterable1, iterable2))))
# ['Ax', 'Ay', 'Bx', 'By', 'Cx', 'Cy', 'Dx', 'Dy']
cf) Itertools
조합, 순열
from itertools import combinations, permutations, combinations_with_replacement
pool = ['A', 'B', 'C']
print(list(map(''.join, permutations(pool)))) # 3개의 원소로 수열 만들기
print(list(map(''.join, permutations(pool, 2)))) # 2개의 원소로 수열 만들기
print(list(map(''.join, combinations(pool, 2))))
print(list(map(''.join, combinations_with_replacement(pool, 2))))
# ['ABC', 'ACB', 'BAC', 'BCA', 'CAB', 'CBA']
# ['AB', 'AC', 'BA', 'BC', 'CA', 'CB']
# ['AB', 'AC', 'BC']
# ['AA', 'AB', 'AC', 'BB', 'BC', 'CC']
Counter
어떤 원소 x가 주어진 시퀀스타입에 몇 번이나 나오는지 countcollections.Counter([iterable-or-mapping])
from collections import Counter
myList = [1, 2, 3, 4, 5, 6, 7, 8, 7, 9, 1, 2, 3, 3, 5, 2, 6, 8, 9, 0, 1, 1, 4, 7, 0]
answer = Counter(myList)
print(answer[1]) # = 4
print(answer[3]) # = 3
print(answer[100]) # = 0
sortedArr = Counter.most_common(answer)
print(sortedArr)
# [(1, 4), (2, 3), (3, 3), (7, 3), (4, 2), (5, 2), (6, 2), (8, 2), (9, 2), (0, 2)]
bisect
이진 탐색 (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))
근데 파이썬은 못 참지..
from bisect import bisect
mylist = [1, 2, 3, 7, 9, 11, 33]
print(bisect(mylist, 3))
_str_()
class 내부의 인스턴스 출력 format을 설정이 가능하다.
class Coord(object):
def __init__ (self, x, y):
self.x, self.y = x, y
def __str__ (self):
return 'str method <<{}, {}>>'.format(self.x, self.y)
point = Coord(1, 2)
print(point) # str method <<1, 2>>
파일 시스템
with - as 구문은 파일 뿐만 아니라 socket이나 http 등에서도 사용 가능
with open('myfile.txt') as file:
for line in file.readlines():
print(line.strip().split('\t'))
EOF
계속 추가하긴 할텐데 뭔가 내가 코딩테스트에 사용할 거 위주로 정리하기 해야 할 것 같다.
오늘도 한 걸음!