파이썬을 파이썬답게

파이썬을 파이썬답게 을 참고하여 정리한 내용입니다.

 

✔️ 시작하기에 앞서

  • iterable : 자신의 멤버를 한 번에 하나씩 리턴할 수 있는 객체입니다. list, str, tuple, dict 등이 여기에 속합니다.
  • sequence : int 타입 인덱스를 통해, 원소에 접근할 수 있는 iterable 입니다. iterable의 하위 카테고리라고 생각하시면 됩니다. list, str, tuple이 여기 속합니다. (dictionary는 다양한 타입을 통해 원소에 접근할 수 있기 때문에 sequence에 속하지 않습니다.)

 

📚 1. Python 꿀팁

Q. 정수를 담은 이차원 리스트가 주어질 때, 각 원소의 길이를 담은 리스트를 리턴하도록 solution 함수를 작성해보기

def solution(mylist):
	return list(map(len, mylist))

 

📚 2. 정수 다루기

📖 A. 몫과 나머지 - divmod

몫 : a//b
나머지 : a%b

한 번에 몫과 나머지를 구할 때 *divmod(a, b)

a = 7
b = 5
print(*divmod(a, b)) # 1 2

작은 숫자를 다룰 때는 a // b, a%b가 더 빠르다.
큰 숫자를 다룰 때는 divmod가 더 빠르다.

 

📖 B. n진법으로 표기된 string을 10진법 숫자로 변환하기

ex) 5진법으로 적힌 문자열 3212를 10진법으로 바꾸기

기본적인 공식

num = '3212'
base = 5

answer = 0
for idx, number in enumerate(num[::-1]):
    answer += int(number) * (base ** idx)

 

파이썬의 int(x, base=10) 함수는 진법 변환을 지원한다.
이 기본적인 함수를 잘쓰면 코드를 짧게 쓸 수 있고, 또 시간을 절약할 수 있다.

num = '3212' # 문자열
base = 5 # 숫자
answer = int(num, base)

 

📚 3. Str 다루기

📖 A. 문자열 정렬하기 - ljust, center, rjust

'가나다라               ' # 좌측정렬
'               가나다라' # 우측 정렬
'       가나다라        ' # 가운데 정렬

기존 코드 방식

### 우측 정렬 예
s = '가나다라'
n = 7

answer = ''
for i in range(n-len(s)): # 문자열의 앞을 빈 문자열로 채우는 for 문
    answer += ' '
answer += s

 

파이썬에서는 ljust, center, rjust와 같은 string의 메소드를 사용해 코드를 획기적으로 줄일 수 있다.

s = '가나다라'
n = 7

s.ljust(n) # 좌측 정렬
s.center(n) # 가운데 정렬
s.rjust(n) # 우측 정렬

 

📖 B. 알파벳 출력하기 - string 모듈

  • 모든 대문자를
  • 또는 모든 소문자를
  • 또는 모든 대소문자를
  • 또는 숫자를

을 쉽게 가져오는 방법

파이썬에서는 이런 데이터를 상수(constants)로 정의해놓았다.

import string 

string.ascii_lowercase # 소문자 abcdefghijklmnopqrstuvwxyz
string.ascii_uppercase # 대문자 ABCDEFGHIJKLMNOPQRSTUVWXYZ
string.ascii_letters # 대소문자 모두 abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ
string.digits # 숫자 0123456789

 

📚 4. Iterable 다루기

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

파이썬의 sort() 함수를 사용하면 리스트의 원소를 정렬할 수 있다.

  • 이때, sort 함수는 원본의 멤버 순서를 변경한다.
  • 원본의 순서는 변경하지 않고, 정렬된 값을 구하려면 sort 함수 대신 sorted 함수를 사용하면 된다.
list1 = [3, 2, 5, 1]
list1.sort()
print(list1) # [1, 2, 3, 5]

list2 = [3, 2, 5, 1]
print(sorted(list2)) # [1, 2, 3, 5]
print(list2) # [3, 2, 5, 1]

 

📖 B. 2차원 리스트 뒤집기 - zip

보통은 2중 for문을 이용해 리스트의 rowcolumn을 뒤집는 문제를 만났을 때

다른 언어들의 코드는

mylist = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
new_list = [[], [], []]

for i in range(len(mylist)):
    for j in range(len(mylist[i])):
        new_list[i].append(mylist[j][i])

이와 같다.

 

파이썬의 zipunpacking을 이용하면 코드 한 줄로 리스트를 뒤집을 수 있다.

mylist = [[1, 2, 3], [4, 5, 6], [7, 8, 9]]
new_list = list(map(list, zip(*mylist)))

 

✔️ zip 함수에 대해

* : unpacking

  • zip(*iterables)는 각 iterables 의 요소들을 모으는 이터레이터를 만듭니다.
  • 튜플의 이터레이터를 돌려주는데, i 번째 튜플은 각 인자로 전달된 시퀀스나 이터러블의 i 번째 요소를 포함합니다.
mylist = [1, 2, 3]
new_list = [40, 50, 60]
for i in zip(mylist, new_list):
    print (i)

# (1, 40)
# (2, 50)
# (3, 60)

 

ex) 여러 개의 iterable 동시에 순회할 때 사용

list1 = [1, 2, 3, 4]
list2 = [100, 120, 30, 300]
list3 = [392, 2, 33, 1]
answer = []
for number1, number2, number3 in zip(list1, list2, list3):
   print(number1 + number2 + number3)

 

ex) Key 리스트Value 리스트로 딕셔너리 생성하기
파이썬의 zip 함수dict 생성자를 이용하면 코드 단 한 줄로, 두 리스트를 합쳐 딕셔너리로 만들 수 있습니다.

animals = ['cat', 'dog', 'lion']
sounds = ['meow', 'woof', 'roar']
answer = dict(zip(animals, sounds)) 

# {'cat': 'meow', 'dog': 'woof', 'lion': 'roar'}

 

📖 C. i번째 원소와 i+1번째 원소 - zip

보통은 i번째에 i+1번째 원소값을 계산하여 i번째에 넣을 때는 이와 같이 접근한다.

def solution(mylist):
    answer = []
    for i in range(len(mylist)-1):
        answer.append(abs(mylist[i] - mylist[i+1]))
    return answer

if __name__ == '__main__':
    mylist = [83, 48, 13, 4, 71, 11]    
    print(solution(mylist))

 

파이썬의 zip을 이용하면 index를 사용하지 않고 각 원소에 접근할 수 있다.

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))
  • zip 함수에 서로 길이가 다른 리스트가 인자로 들어오는 경우에는 길이가 짧은 쪽 까지만 이터레이션이 이루어진다.

 

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

파이썬의 map을 사용하면 for문을 사용하지 않고도 멤버의 타입을 일괄 변환할 수 있다.

list1 = ['1', '100', '33']
list2 = list(map(int, list1))

 

✔️ 정수를 담은 이차원 리스트에서 각 원소의 길이를 담은 리스트

def solution(mylist):
	answer = list(map(len, mylist))
	return answer

 

📚 5. Sequence Types 다루기

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

ex)

  • 문자열 배열 ['1', '100', '33']을 이어 붙여 문자열 '110033' 만들기
  • 정수형 튜플 (3, 22, 91)을 이어붙여 문자열 '32291' 만들기

파이썬의 str.join(iterable)을 사용하면 된다.

my_list = ['1', '100', '33']
answer = ''.join(my_list)

 

📖 B. 삼각형 별찍기 - sequence type의 * 연산

ex)

  • 'abc', 'abcabc', 'abcabcabc', 'abcabcabcabc ...' 과 같이 'abc'가 n번 반복되는 문자열 만들기
  • [123, 456, 123, 456, 123, ...] 과같이 123, 456이 n번 반복되는 리스트 만들기

파이썬에서는 * 연산자를 사용해 코드를 획기적으로 줄일 수 있다.

n = 어쩌고
answer = 'abc' * n

또한, * 연산자를 이용하면 123, 456이 n번 반복되는 리스트를 만들 수 있다.

n = 어쩌고
answer= [123, 456] * n

 

📚 6. Itertools/Collections 모듈

📖 A. 곱집합(Cartesian product) 구하기 - product

ex) 두 스트링 'ABCD', 'xy' 의 곱집합은 Ax Ay Bx By Cx Cy Dx Dy 입니다.

파이썬에서는 itertools.product를 이용하면, for문을 사용하지 않고도 곱집합을 구할 수 있다.

import itertools

iterable1 = 'ABCD'
iterable2 = 'xy'
iterable3 = '1234'
print(list(itertools.product(iterable1, iterable2, iterable3)))

실행 결과

[('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')]

 

📖 B. 2차원 리스트를 1차원 리스트로 만들기 - from_iterable

파이썬의 다양한 기능을 사용하면, for문을 사용하지 않고도 리스트를 이어 붙일 수 있다.

my_list = [[1, 2], [3, 4], [5, 6]]

# 방법 1 - sum 함수 o
answer = sum(my_list, [])

# 방법 2 - itertools.chain x
import itertools
list(itertools.chain.from_iterable(my_list))

# 방법 3 - itertools와 unpacking o
import itertools
list(itertools.chain(*my_list))

# 방법 4 - list comprehension 이용 x
[element for array in my_list for element in array]

# 방법 5 - reduce 함수 이용 1 x
from functools import reduce
list(reduce(lambda x, y: x+y, my_list))

# 방법 6 - reduce 함수 이용 2 x
from functools import reduce
import operator
list(reduce(operator.add, my_list))

 

📖 C. 순열과 조합 - permutations, combinations

ex)

  • 1,2,3의 숫자가 적힌 카드가 있을 때, 이 중 두 장을 꺼내는 경우의 수 → 12, 13, 21, 23, 31, 32
  • 'A', 'B', 'C'로 만들 수 있는 경우의 수 → 'ABC', 'ACB', 'BAC', 'BCA', 'CAB', 'CBA'

파이썬에서는 itertools.permutation을 이용하면, for문을 사용하지 않고도 순열을 구할 수 있다!

import itertools

pool = ['A', 'B', 'C']
print(list(map(''.join, itertools.permutations(pool)))) # 3개의 원소로 수열 만들기
print(list(map(''.join, itertools.permutations(pool, 2)))) # 2개의 원소로 수열 만들기

실행 결과

['ABC', 'ACB', 'BAC', 'BCA', 'CAB', 'CBA']
['AB', 'AC', 'BA', 'BC', 'CA', 'CB']

 

📖 D. 가장 많이 등장하는 알파벳 찾기 - Counter

알고리즘 문제를 풀다 보면 어떤 원소 x가 주어진 시퀀스타입에 몇 번이나 등장하는지 세야 할 때가 있다.

이때는, 파이썬의 collections.Counter 클래스를 사용하면 된다!

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[1]) # = 4
print(answer[3])  # = 3
print(answer[100]) # = 0

 

✔️ 상위 요소 반환 : most_common()

most_common() 메서드를 사용하면 인자만큼 상위요소를 출력할 수 있다.

Counter('aaaaabbbcc').most_common(1) # 상위 요소 하나 출력
# [('a', 5)]
Counter('aaaaaaabbbcc').most_common(2) # 상위 요소 두개 출력
# [('a', 5), ('b', 3)]

 

📚 7. 기타

📖 A. for 문과 if문을 한번에 - List comprehension의 if 문

파이썬에서는 list comprehension을 사용하면 한 줄 안에 for문과 if문을 한 번에 처리할 수 있다.

mylist = [3, 2, 6, 7]
answer = [number**2 for number in mylist if number % 2 == 0]

 

📖 B. flag 대신 for-else 사용하기

보통 성공, 실패를 확인할 때 bool check을 주어 true, false로 판단한다.

파이썬에서는 for-else문을 사용하면 코드를 짧게 쓸 수 있고, 그 의미를 알아보기 쉽다!

import math

if __name__ == '__main__':
    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')

 

arr = [1, 2, 3, 4]

for a in arr:
    if a == 5:
        print('found')
        break
else:
    print('not found')

실행 결과

not found

 

📖 C. 두 변수의 값 바꾸기 - swap

ex) a=3, b='abc' ↔️ a='abc', b=3

파이썬에서는 한 줄로 두 값을 바꿔치기할 수 있다!

a = 3
b = 'abc'
a, b = b, a

 

📖 D. 이진 탐색하기 - binary search

bisect : Python의 이진 탐색 모듈
이진 탐색 : 오름차순으로 정렬된 리스트에서 특정한 값의 위치를 찾는 알고리즘. 검색 속도가 아주 빠르다.

파이썬에서는 bisect.bisect 메소드를 사용하면 이진 탐색을 쉽게 구현할 수 있다.

import bisect
mylist = [1, 2, 3, 7, 9, 11, 33]
print(bisect.bisect(mylist, 3))
  • bisect_left(literable, value) : 왼쪽 인덱스를 구하기
  • bisect_right(literable, value) : 오른쪽 인덱스를 구하기

bisect 추가 정리된 곳

 

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

ex) 2차원 평면 위의 점을 나타내는 Coord 클래스의 인스턴스를 (x 값, y 값)으로 출력하기

파이썬에서는 __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)


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

실행 결과

(1, 2)

 

📖 F. 가장 큰 수, inf

코딩 테스트 문제 등을 풀다 보면, 최솟값을 저장하는 변수에 아주 큰 값을 할당해야 할 때가 있다.
이때는 inf를 사용한다.

파이썬에서 inf를 제공하는데, inf는 어떤 숫자와 비교해도 무조건 크다고 판정된다!

min_val = float('inf')

inf에 음수 기호를 붙이는 것도 가능하다.

max_val = float('-inf')

 

📖 G. 파일 입출력 간단하게 하기

'myfile.txt'라는 이름의 파일을 읽는 코드

파이썬에서는 with-as 구문을 이용하면 코드를 더 간결하게 짤 수 있다.

with open('myfile.txt') as file:
    for line in file.readlines():
        print(line.strip().split('\t'))

장점

  • 파일을 close 하지 않아도 된다. with - as 블록이 종료되면 파일이 자동으로 close 된다.
  • readlines가 EOF까지만 읽으므로, while 문 안에서 EOF를 체크할 필요가 없다.

좋은 웹페이지 즐겨찾기