TIL - How to Python "pythonically"

Seob·2020년 7월 10일
2

TIL

목록 보기
9/36

💡프로그래머스 - '파이썬을 파이썬답게' 강의를 공부하며 작성했습니다.

맛보기쓰

평범쓰 😔

def solution(mylist):
    answer=[]
    for i in mylist:
        answer.append(len(i))
    return answer

pythonic 🥰

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

정수 다루기

몫과 나머지

🤔

a, b = map(int, input().strip().split(' '))
print(a//b, a%b)

pythonic 🙂

a, b = map(int, input().strip().split(' '))
print(*divmod(a, b))
  • divmod()는 내장함수이다.
  • divmod 앞에 *가 없으면 (1, 2)처럼 튜플 형태로 반환하기 때문에 unpacking해준 것
    👆🏻참조

    무조건 divmod를 사용하는 게 좋은 방법은 아니라고 한다.
    가독성이나, 팀의 코드 스타일에 따라서, a//b, a%b와 같이 쓸 때가 더 좋을 수 있고, divmod작은 숫자를 다룰 때는 a//b, a%b 보다 느리다. 대신, 큰 숫자를 다룰 때는 전자가 후자보다 더 빠르다.
    퍼포먼스 차이 참고 👉🏻 stack overflow

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

🤔

다른 언어나 이 방법을 모르는 경우

num = '3212'
base = 5

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

pythonic 🙂

num = '3212'
base = 5
answer = int(num, base)

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

Str 다루기

문자열 정렬하기

🤔

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

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

pythonic 🙂

s, n = input().strip().split(' ')
n = int(n)
print(s.ljust(n))
print(s.center(n))
print(s.rjust(n))

string.ljust(length, character)
string.rjust(length, character)
string.center(length, character)
모두string methods 이다.

txt = "poop"
x = txt.center(20, "💩")
print(x)
>>
💩💩💩💩💩💩💩💩poop💩💩💩💩💩💩💩💩

알파벳 출력하기

🤔

num = int(input().strip())
a = 'abcdefghijklmnopqrstuvwxyz'
print(a) if num == 0 else print(a.upper())

pythonic 🙂

import string 

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

파이썬에서는 이런 부분을 상수(constant)로 정의해놓았다.
더 많은 string constants 보기👈🏻

Iterable 다루기

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

이 부분은 앞에서 정리해서 PASS!
TIL - sort, reverse vs sorted, reversed

2차원 리스트 뒤집기

내가 생각해본 pythonic answer 🤔

def solution(mylist):
    answer = [[mylist[j][i] for j in range(len(mylist[i]))] for i in range(len(mylist))]      
    return answer

pythonic 🙂

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

2중 for loop을 하지 않고도 zip()함수로 간단히 해결된다.

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 동시에 순회

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 리스트로 딕셔너리 생성

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

모든 멤버의 type 변환하기

🤔

list1 = ['1', '100', '33']
list2 = []
for i in list1:
    list2.append(int(i))

내가 작성한 pythonic answer 🙂

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

아무것도 모르고 알고리즘 연습문제들을 풀다가 map() 함수를 알게 되었는데 이번 문제를 푸는데 도움이 되었다. 🙌🏻

map 함수 응용하기

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

Sequence type 다루기

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

🤔

my_list = ['1', '100', '33']
answer = ''
for i in my_list:
    answer += i

내가 작성한 pythonic answer 🙂

def solution(mylist):
    return ''.join(mylist)

이 문제 역시 알고리즘 연습문제를 풀어서 join()함수를 알게 되었고 쉽게 풀 수 있었다.

점프 투 파이썬 👈🏻

삼각형 별찍기 - *연산 활용

내가 작성한 답

n = int(input().strip())
for i in range(1, n+1):
    print('*'*)

보너스 🙂

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

n = 5
answer = [123, 456]*n
print(answer)
>>>
[123, 456, 123, 456, 123, 456, 123, 456, 123, 456]

Itertools / Collections 모듈

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

iterable로 곱집하는 구하는 방법을 알아보자.

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

🤔

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
.
.
.
(생략)

pythonic 🙂

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

import itertools

iterable1 = 'ABCD'
iterable2 = 'xy'
iterable3 = '1234'

print(set(itertools.product(iterable1, iterable2, iterable3)))
>>>
{('C', 'y', '4'), ('A', 'x', '4'), ('C', 'x', '2'), ('D', 'y', '2'), ('B', 'x', '1'), ('B', 'x', '3'), ('A', 'y', '1'), ('A', 'y', '3'), ('D', 'x', '1'), ('D', 'x', '3'), ('B', 'y', '4'), ('B', 'x', '2'), ('C', 'x', '4'), ('A', 'y', '2'), ('D', 'y', '4'), ('D', 'x', '2'), ('C', 'y', '1'), ('A', 'x', '1'), ('A', 'x', '3'), ('C', 'y', '3'), ('B', 'x', '4'), ('C', 'y', '2'), ('A', 'x', '2'), ('D', 'x', '4'), ('A', 'y', '4'), ('B', 'y', '1'), ('B', 'y', '3'), ('C', 'x', '1'), ('C', 'x', '3'), ('D', 'y', '1'), ('B', 'y', '2'), ('D', 'y', '3')}

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

🤔

my_list = [[1, 2], [3, 4], [5, 6]]
answer = []
for i in my_list:
    answer += i

pythonic 🙂

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))

# 방법 7 - numpy 라이브러리의 flatten 이용
import numpy as np
np.array(my_list).flatten().tolist()

순열과 조합 - combinations, permutations

예시)

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

for 문으로 구현한 경우 🤔

def permute(arr):
    result = [arr[:]]
    c = [0] * len(arr)
    i = 0
    while i < len(arr):
        if c[i] < i:
            if i % 2 == 0:
                arr[0], arr[i] = arr[i], arr[0]
            else:
                arr[c[i]], arr[i] = arr[i], arr[c[i]]
            result.append(arr[:])
            c[i] += 1
            i = 0
        else:
            c[i] = 0
            i += 1
    return result

itertools.permutation를 이용 🙂

import itertools

def solution(mylist):
    answer = list(map(list, itertools.permutations(mylist)))
    answer.sort()
    return answer
>>>
[[1, 2, 3], [1, 3, 2], [2, 1, 3], [2, 3, 1], [3, 1, 2], [3, 2, 1]]
[[1, 2], [2, 1]]
import itertools
pool = ['A', 'B', 'C']
print(list(map(''.join, itertools.permutations(pool)))) # 3개의 원소로 수열 만들기
print(list(map(''.join, itertools.permutations(pool, 2)))) # 2개의 원소로 수열 만들기

앞에서 공부한 map()join 함수를 함께 사용하여 간단하게 구현할 수 있다! 😎

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

🤔

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 = {}
for number in my_list:
    try:
        answer[number] += 1
    except KeyError:
        answer[number] = 1

print(answer[1]) # = 4
print(answer[3])  # = 3
print(answer[100])  # =  raise KeyError

pythonic 🙂

import collections

my_str = input()
my_str = sorted(my_str)
counter = collections.Counter(my_str).most_common()
collect = [counter[i][0] for i in range(len(counter)) if counter[i][1] == counter[0][1]]
answer = ''.join(collect)
print(answer)
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

기타🎸

for 문과 if문을 한번에

🤔

mylist = [3, 2, 6, 7]
answer = []
for i in mylist:
    if i%2 == 0:
        answer.append(i**2) # 들여쓰기를 두 번 함

pythonic 🙂

def solution(mylist):
    return [i**2 for i in mylist if i%2 ==0]
mylist = [3, 2, 6, 7]
answer = [ i**2 for i in mylist if i %2 == 0]

flag OR else

🤔

import math

numbers = [int(input()) for _ in range(5)]
multiplied = 1
flag = True
for number in numbers:
    multiplied *= number
    if math.sqrt(multiplied) == int(math.sqrt(multiplied)):
        flag = False
        print('found')
        break

if flag:
    print('not found')

pythonic 🙂

import math

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')

두 변수의 값 바꾸기 - swap

a = 'abc', b = 3a = 3, b = 'abc'로 바꾸기

🤔

a = 3
b = 'abc'

temp = a
a = b
b = temp

pythonic 🙂

a = 3
b = 'abc'

a, b = b, a # 참 쉽죠?

🤔

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

pythonic 🙂

import bisect
mylist = [1, 2, 3, 7, 9, 11, 33]
print(bisect.bisect(mylist, 3))
>>>
3

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

파일 입출력 간단하게 하기

🤔

f = open('myfile.txt', 'r')
while True:
    line = f.readline()
    if not line: break
    raw = line.split()
    print(raw)
f.close()

pythonic 🙂

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

파이썬의 with - as 구문을 이용하면 코드를 더 간결하게 짤 수 있습니다. 코드를 아래와 같이 쓰면 다음과 같은 장점이 있습니다.
파일을 close 하지 않아도 됩니다: with - as 블록이 종료되면 파일이 자동으로 close 됩니다.
readlines가 EOF까지만 읽으므로, while 문 안에서 EOF를 체크할 필요가 없습니다
⨳ with - as 구문은 파일 뿐만 아니라 socket이나 http 등에서도 사용할 수 있습니다.
프로그래머스

profile
Hello, world!

0개의 댓글