본문으로 바로가기

파이썬을 파이썬답게

category language 2019. 9. 16. 21:19

https://programmers.co.kr/learn/courses/4008


복습할 겸 해서 위의 강의를 수강하면서 실습!

부가적으로 공부한 부분도 있다.


divmod

몫과 나머지 구하기

In [2]:
a, b = 29, 3
a, b = divmod(a, b)
print(a, b)
9 2
In [3]:
a, b = 29, 3
a, b = a//b, a%b
print(a, b)
9 2

같은 결과값을 출력한다.
작은 숫자를 다룰 때는 아래와 같은 방식이 더 빠르고, 큰 수를 다룰 때는 위와 같은 방식이 더 빠르다.

int(num, base)

진법 변환

In [12]:
num, base = '3212', 5
answer = 0
for idx, x in enumerate(num[::-1]):
    answer = answer + int(x)*(base**idx)
answer
Out[12]:
432
In [11]:
num = '3212'
base = 5
answer = int(num, base) # base의 default값은 10
answer
Out[11]:
432

같은 결과값을 출력한다.

ljust, center, rjust

문자열 왼쪽 정렬, 가운데 정렬, 오른쪽 정렬

In [13]:
s, n = 'abc', 7
n = int(n)
a = s+' '*(n-len(s))
c = ' '*(n-len(s))+s
b = ' '*((n-len(s))//2) + s + ' '*((n-len(s))//2)
print(a)
print(b)
print(c)
abc    
  abc  
    abc
In [15]:
print(s.ljust(n))
print(s.center(n))
print(s.rjust(n))
abc    
  abc  
    abc

같은 결과를 출력한다.

string의 상수

In [17]:
# 입력에 따라 모든 영문 대문자 혹은 소문자 출력
num = int(input().strip())
zero = ('').join([chr(i) for i in range(97, 123)])
one = ('').join([chr(i) for i in range(65, 91)])
if num == 0:
    print(zero)
if num == 1:
    print(one)
1
ABCDEFGHIJKLMNOPQRSTUVWXYZ
In [18]:
import string 

string.ascii_lowercase # 소문자 abcdefghijklmnopqrstuvwxyz
string.ascii_uppercase # 대문자 ABCDEFGHIJKLMNOPQRSTUVWXYZ
string.ascii_letters #대소문자 모두 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
string.digits # 숫자 0123456789
Out[18]:
'0123456789'

파이썬에서는 이러한 것들을 상수로 정의해두었다.

원본을 유지한채, 정렬된 리스트 구하기 - sorted

In [19]:
a = [3,2,1]
b = sorted(a, reverse = False)
b
Out[19]:
[1, 2, 3]

list의 메서드로 sort()도 있다. 이는 return None으로 inplace 저장되는 메서드이므로 주의.

2차원 리스트 뒤집기

In [20]:
def solution(mylist):
    answer = []
    answer = [[] for _ in mylist]
    for idx in mylist:
        for jdx, item in enumerate(idx):
            answer[jdx].append(item)
    return answer
In [21]:
mylist = [ [1,2,3], [4,5,6], [7,8,9] ]
new_list = list(map(list, zip(*mylist)))
new_list
Out[21]:
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]

zip과 unpacking을 이용하여 리스트를 뒤집을 수 있다.

zip(*iterables)는 각 iterables 의 요소들을 모으는 이터레이터를 만듭니다.
튜플의 이터레이터를 돌려주는데, i 번째 튜플은 각 인자로 전달된 시퀀스나 이터러블의 i 번째 요소를 포함합니다.

In [23]:
mylist = [ 1,2,3 ]
new_list = [ 40, 50, 60 ]
for i in zip(mylist, new_list):
    print (i)
(1, 40)
(2, 50)
(3, 60)

여러 개의 Iterable 동시에 순회할 때 사용

In [25]:
list1 = [1, 2, 3, 4]
list2 = [100, 120, 30, 300]
list3 = [392, 2, 33, 1]
answer = []
for i, j, k in zip(list1, list2, list3):
    print( i + j + k )
493
124
66
305

Key 리스트와 Value 리스트로 딕셔너리 생성

In [26]:
animals = ['cat', 'dog', 'lion']
sounds = ['meow', 'woof', 'roar']
answer = dict(zip(animals, sounds))
answer
Out[26]:
{'cat': 'meow', 'dog': 'woof', 'lion': 'roar'}

모든 멤버의 type 변환하기 - map

In [27]:
answer = ['1', '2', '3']
answer = [ int(_) for _ in mylist]
answer
Out[27]:
[1, 2, 3]
In [29]:
list1 = ['1', '2', '3']
list2 = list(map(int, list1))
list2
Out[29]:
[1, 2, 3]

같은 결과값

sequence 멤버를 하나로 이어붙이기 - join

In [30]:
my_list = ['1', '100', '33']
answer = ''.join(my_list)
In [31]:
answer = ('').join(my_list)

괄호를 붙여도 되고 안 붙여도 된다.

삼각형 별찍기

In [32]:
n = int(input().strip())
for i in range(1, n+1):
    print('*'*i)
3
*
**
***

곱집합(Cartesian product) 구하기 - product

In [33]:
iterable1 = 'ABCD'
iterable2 = 'xy'
iterable3 = '1234'

for i in iterable1:
    for j in iterable2:
        for k in iterable3:
            print(i+j+k)
Ax1
Ax2
Ax3
Ax4
Ay1
Ay2
Ay3
Ay4
Bx1
Bx2
Bx3
Bx4
By1
By2
By3
By4
Cx1
Cx2
Cx3
Cx4
Cy1
Cy2
Cy3
Cy4
Dx1
Dx2
Dx3
Dx4
Dy1
Dy2
Dy3
Dy4
In [35]:
import itertools

iterable1 = 'ABCD'
iterable2 = 'xy'
iterable3 = '1234'
itertools.product(iterable1, iterable2, iterable3)
for i in itertools.product(iterable1, iterable2, iterable3):
    print(i)
('A', 'x', '1')
('A', 'x', '2')
('A', 'x', '3')
('A', 'x', '4')
('A', 'y', '1')
('A', 'y', '2')
('A', 'y', '3')
('A', 'y', '4')
('B', 'x', '1')
('B', 'x', '2')
('B', 'x', '3')
('B', 'x', '4')
('B', 'y', '1')
('B', 'y', '2')
('B', 'y', '3')
('B', 'y', '4')
('C', 'x', '1')
('C', 'x', '2')
('C', 'x', '3')
('C', 'x', '4')
('C', 'y', '1')
('C', 'y', '2')
('C', 'y', '3')
('C', 'y', '4')
('D', 'x', '1')
('D', 'x', '2')
('D', 'x', '3')
('D', 'x', '4')
('D', 'y', '1')
('D', 'y', '2')
('D', 'y', '3')
('D', 'y', '4')
In [36]:
itertools.product(iterable1, iterable2, iterable3)
Out[36]:
<itertools.product at 0x105339630>

그냥 프린트하려고 하면 이렇게 iterable 객체를 출력하고, for문 또는 list comprehension으로 출력하면 값을 확인 가능하다.

2차원 리스트를 1차원 리스트로 만들기

In [37]:
def solution(mylist):
    answer = list()
    for idx in mylist:
        answer.extend(idx)
    return answer
In [38]:
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))
Out[38]:
[1, 2, 3, 4, 5, 6]

reduce(함수, 순서형 자료)
순서형 자료(문자열, 리스트, 튜플)의 원소들을 누적적으로 함수에 적용시킨다.

순열과 조합

In [39]:
import itertools
def solution(mylist):
    answer = [list(idx) for idx in itertools.permutations(mylist)]
    answer.sort()
    return answer

가장 많이 등장하는 알파벳 찾기

In [40]:
my_str = input().strip()
maxdict = dict()
maxstr = 0
for idx in my_str:
    if idx not in maxdict.keys():
        maxdict[idx] = 1
        if maxdict[idx] > maxstr:
            maxstr = maxdict[idx]
    else:
        maxdict[idx] += 1
        if maxdict[idx] > maxstr:
            maxstr = maxdict[idx]
answer = [ k for k, v in maxdict.items() if v == maxstr]
answer.sort()
answer = ''.join(answer)
print(answer)
bbaa
ab
In [41]:
import collections
my_list = [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 = collections.Counter(my_list)
print(answer)
Counter({1: 4, 2: 3, 3: 3, 7: 3, 4: 2, 5: 2, 6: 2, 8: 2, 9: 2, 0: 2})

collections의 counter를 이용해 간단하게 등장 갯수를 셀 수 있다.
요소의 개수가 많은 것부터 출력

In [42]:
import collections
c = collections.Counter(a=2, b=3, c=2)
print(collections.Counter(c))
print(sorted(c.elements()))
Counter({'b': 3, 'a': 2, 'c': 2})
['a', 'a', 'b', 'b', 'b', 'c', 'c']

값 = 개수를 입력값으로 줄 수도 있다.

In [43]:
c.update('abc&##39;)
c
Out[43]:
Counter({'a': 3, 'b': 4, 'c': 3})

update()는 Counter의 값을 갱신하는 것을 의미한다.

In [44]:
c.items()
Out[44]:
dict_items([('a', 3), ('b', 4), ('c', 3)])

dictionary의 items() 메서드와 같다.

In [48]:
c.elements()
Out[48]:
<itertools.chain at 0x10564f978>
In [49]:
list(c.elements())
Out[49]:
['a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c']

입력된 값의 요소에 해당하는 값을 풀어서 반환한다. 요소는 무작위로 반환하며, 요소 수가 1보다 작을 경우 elements는 이를 출력하지 않는다.

In [50]:
sorted(c.elements())
Out[50]:
['a', 'a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c']

iterable이므로 sorted() 사용 가능

In [51]:
c.most_common(1)
Out[51]:
[('b', 4)]

등장 빈도수가 높은 순으로 상위 n개를 list(tuple) 형태로 변환하여 출력한다.

In [52]:
c.most_common()
Out[52]:
[('b', 4), ('a', 3), ('c', 3)]

n을 입력하지 않은 경우 전체에 대한 등장 빈도수를 내림차순으로 출력한다.

In [53]:
c.subtract('abc')
c
Out[53]:
Counter({'a': 2, 'b': 3, 'c': 2})

말 그대로 요소를 빼는것을 의미한다. 다만, 요소가 없는 경우는 음수의 값이 출력된다.

In [54]:
c.subtract('z')
c
Out[54]:
Counter({'a': 2, 'b': 3, 'c': 2, 'z': -1})

Counter는 산술 연산이 가능하다.

In [55]:
a = collections.Counter(['a', 'b', 'c', 'b', 'd', 'a'])
b = collections.Counter('aaeroplane')
print(a)
print(b)
print(a+b)
Counter({'a': 2, 'b': 2, 'c': 1, 'd': 1})
Counter({'a': 3, 'e': 2, 'r': 1, 'o': 1, 'p': 1, 'l': 1, 'n': 1})
Counter({'a': 5, 'b': 2, 'e': 2, 'c': 1, 'd': 1, 'r': 1, 'o': 1, 'p': 1, 'l': 1, 'n': 1})
In [56]:
import collections
a = collections.Counter('aabbccdd')
b = collections.Counter('abbbce')
print(a-b)
Counter({'d': 2, 'a': 1, 'c': 1})

Counter의 뺄셈은 음수값은 출력하지 않는다.

In [57]:
import collections
a = collections.Counter('aabbccdd')
b = collections.Counter('aabbbce')
print(a & b)
Counter({'a': 2, 'b': 2, 'c': 1})

교집합(&) : 딕셔너리 형태로 반환된다.

In [58]:
print(a | b)
Counter({'b': 3, 'a': 2, 'c': 2, 'd': 2, 'e': 1})

합집합(|) : 딕셔너리 형태로 반환된다.

출처 : https://excelsior-cjh.tistory.com/96?category=966334

list comprehension

In [59]:
def solution(mylist):
    answer = [i**2 for i in mylist if i%2 == 0]
    return answer

swap

In [60]:
a = 1
b = 2
a, b = b, a
print(a, b)
2 1

bisect

python의 이진 탐색 모듈

In [61]:
import bisect
mylist = [1, 2, 3, 7, 9, 11, 33]
print(bisect.bisect(mylist, 3))
3
In [62]:
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))
2

클래스 인스턴스 출력하기 - class의 자동 string casting

In [63]:
class Coord(object):
    def __init__ (self, x, y):
        self.x, self.y = x, y
    def __str__ (self):
        return '({}, {})'.format(self.x, self.y)

point = Coord(1, 2)
print(point)
(1, 2)

가장 큰 수, inf

In [67]:
min_val = float('inf')
max_val = float('-inf')

비교 문제에서 초기화할 때 요긴하다.

파일 입출력 간단하게 하기

with open('file.txt') as f:
do something

  1. 파일을 close 하지 않아도 됩니다: with - as 블록이 종료되면 파일이 자동으로 close 됩니다.
  2. readlines가 EOF까지만 읽으므로, while 문 안에서 EOF를 체크할 필요가 없습니다.
In [68]:
# with open('myfile.txt') as file:
#   for line in file.readlines():
#     print(line.strip().split('\t'))

socket이나 http 등에서도 사용 가능하다.

파이썬을 파이썬답게