[알고리즘] 0. Python 기본 문법
/* '이것이 취업을 위한 코딩 테스트다' 책의 저자이신 나동빈 님의 예시와 제가 학교 수업에서 배운 내용을 바탕으로 정리했습니다. */
1. 자료형 (Data Type)
(1) 정수형
x = 5
print("type() : ", type(x))
print("x : ", x)
< 출력 >
type() : <class 'int'>
x : 5
x = 5
print("x : ", x)
x += 10
print("x : ", x)
< 출력 >
x : 5
x : 15
(2) 실수형
fl = 15.111
print("type() : ", type(fl))
print("fl : ", fl)
< 출력 >
type() : <class 'float'>
fl : 15.111
fll = 5.
print("fll : ", fll)
exp = int(1e9)
print("exp : ", exp)
exp의 값은 e 다음에 오는 숫자의 거듭제곱으로 10을 곱한다. (1 * (10)^9)
< 출력 >
fll : 5.0
exp : 1000000000
※ 컴퓨터는 모든 정보를 0과 1 (이진법)으로 다루기 때문에 오류가 발생할 수 있다.
a = 0.3 + 0.6
print("a : ", a)
if a == 0.9:
print("a == 0.9")
else:
print("a != 0.9")
우리는 a의 값이 당연히 0.9라고 생각하지만, 컴퓨터는 그렇게 받아들이지 않기 때문에...!
round() 함수가 필요하다.
< 출력 >
a : 0.8999999999999999
a != 0.9
a = 0.3 + 0.6
print("a : ", a)
a = round(a, 2)
print("a : ", a)
if a == 0.9:
print("a == 0.9")
else:
print("a != 0.9")
round(숫자, 소숫점 아래 몇번째인지)
위의 예시에서는 소숫점 아래 두번째에서 반올림한다.
< 출력 >
a : 0.8999999999999999
a : 0.9
a == 0.9
(3) 수 자료형의 연산
a = 7
b = 3
print("a / b = ", a/b)
print("a % b = ", a % b)
print("a // b = ", a//b)
print("a ** b = ", a**b)
< 출력 >
a / b = 2.3333333333333335
a % b = 1
a // b = 2
a ** b = 343
(4) 리스트 자료형
- 리스트 초기화 : [], list()
lst = [7, 5, 7, 4, 3, 6, 5]
print("type() : ", type(lst))
print("lst : ", lst)
print("lst[:4] : ", lst[:4])
< 출력 >
type() : <class 'list'>
lst : [7, 5, 7, 4, 3, 6, 5]
lst[:4] : [7, 5, 7, 4]
- list comprehension (리스트 컴프리헨션)
: 리스트를 더 간결하게 작성하는 방법!
com_lst = [i for i in range(10)]
print(com_lst)
com_lst2 = [i*2 for i in range(5)]
print(com_lst2)
com_lst3 = [i for i in range(20) if i % 2 == 0]
print(com_lst3)
com_lst는 range(10)의 원소 값들로 만든 리스트이고,
com_lst2는 range(5)의 원소를 2배해서 만든 리스트이며,
com_lst3는 range(20)의 원소 중에서 2의 배수인 수들로 만든 리스트이다.
(for문으로 리스트를 만들고 그 안에 if문을 넣어주는 것보다 훨씬 짧아서 보기도 좋은 것 같다..ㅎ!)
< 출력 >
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 2, 4, 6, 8]
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18]
※ list comprehension은 특히 2차원 리스트를 초기화할 때 효과적이다!
일단, 파이썬에서의 언더바(_)는 반복을 수행하되, 반복을 위한 변수의 값을 무시하고자 할 때 사용한다.
for _ in range(5):
print("Hello World")
< 출력 >
Hello World
Hello World
Hello World
Hello World
Hello World
row = 5
column = 4
array = [[0]*column for _ in range(row)]
print(array)
모든 원소의 값을 0으로 초기화 한 5x4 2차원 배열이 만들어졌다.
< 출력 >
[[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]
- 리스트 유용한 함수
a = [4, 3, 2, 1]
print(a)
a.reverse()
print(a)
a.insert(2, 10)
print(a)
print(a.count(2))
a.remove(1)
print(a)
< 출력 >
[4, 3, 2, 1]
[1, 2, 3, 4]
[1, 2, 10, 3, 4]
1
[2, 10, 3, 4]
- 리스트에서 특정 값을 가지는 원소 모두 제거하기
lst = [1, 2, 3, 3, 3, 3, 3, 4, 5, 6, 6, 6]
remove_set = {3, 6}
lst = [i for i in lst if i not in remove_set]
print(lst)
< 출력 >
[1, 2, 4, 5]
(5) 문자열 자료형
str = "Hello"
print(str)
print("len() : ", len(str))
< 출력 >
Hello
len() : 5
(6) 튜플 자료형
: unchangeable (추가, 삭제, 수정 다 불가능!!)
- 튜플 자료형을 사용하면 좋은 경우 : 서로 다른 성질의 데이터를 묶어서 관리해야 할 때
- 최단 경로 알고리즘 (비용, 노드 번호)의 형태로 튜플 자료형을 자주 관리할 때
- 데이터의 나열을 해싱 (Hashing)의 키 값으로 사용해야 할 때
- 튜플은 변경이 불가능하므로 리스트와 다르게 키 값으로 사용될 수 있음
- 리스트보다 메모리를 더 효율적으로 사용할 수 있음
tup = (1, 2, 3, 4, 5, 5, 5, 6)
print(tup)
< 출력 >
(1, 2, 3, 4, 5, 5, 5, 6)
(6) 사전 자료형
- 해시 테이블을 이용하므로 데이터의 조회 및 수정이 O(1)의 시간에 처리된다.
fruit = dict()
fruit['A'] = 'apple'
fruit['B'] = 'banana'
fruit['M'] = 'mango'
fruit['S'] = 'strawberry'
print(fruit.keys())
print(fruit.values())
< 출력 >
dict_keys(['A', 'B', 'M', 'S'])
dict_values(['apple', 'banana', 'mango', 'strawberry'])
(7) 집합 자료형
- 중복 허용 안하고 순서 없음
sset = set([1, 1, 1, 1, 5, 5, 3, 5, 6, 6, 2])
print(sset)
< 출력 >
{1, 2, 3, 5, 6}
2. 표준 입력 방법
- input() : 한 줄의 문자열을 입력 받는 함수
- map() : 리스트의 모든 원소에 각각 특정한 함수를 적용할 때 사용
map (함수, 반복가능자료형)
lst = [1, 2, 3, 4, 5]
def add_one(n):
return n+1
result = list(map(add_one, lst))
print(result)
map 함수에 add_one 함수와 lst 리스트를 넣어주었더니
알아서 lst의 모든 원소에 1이 더해진 값을 얻을 수 있었다. 코드가 매우 간결해지고 빨라진 것을 알 수 있다!!
num = int(input())
data = list(map(int, input().split()))
data.sort(reverse=True)
print(data)
input()는 입력 받은 값을 하나의 문자열로 인식한다.
그래서 split()으로 공백을 기준으로 하여 숫자들끼리 분리해준다.
왜 map 함수가 필요할까?
map 함수 없이 int 함수로 공백 기준으로 자른 문자열 (숫자로 보이는)을 정수로 바꾼다고 해보자.
data = list(int(input().split()))
print(data)
< 출력 >
Traceback (most recent call last):
File "c:\Users\Kong JiYun\Desktop\Algorithm\ptyhon\practice.py", line 1, in <module>
data = list(int(input().split()))
TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'
에러가 난다..!
int 함수는 리스트 자료형을 정수로 바꿀 수 없다고 한다.
map 함수를 적극적으로 활용해야겠다.
- 사용자로부터 입력을 최대한 빠르게 받아야하는 경우
: sys 라이브러리에 정의되어 있는 sys.stdin.readline() 사용!
입력 후 엔터가 줄 바꿈 기호로 입력되므로 rstrip() 메서드를 함께 사용한다.
import sys
a = int(sys.stdin.readline().rstrip())
print(a)
- 임의의 정수 나열을 받아서 list에 저장할 경우 (sys 라이브러리 + map 함수)
import sys
num_input = list(map(int, sys.stdin.readline().split()))
print(num_input)
< 출력 >
1 2 3 4 5
[1, 2, 3, 4, 5]
- f-string
: 문자열 앞에 f를 붙여서 사용한다.
answer = 100
print(f"The answer is {answer}.")
< 출력 >
The answer is 100.
3. 조건문
if True:
print("Yes")
else:
print("No")
< 출력 >
Yes
- 조건부 표현식
score = 85
result = "Success" if score >= 80 else "Fail"
print(result)
< 출력 >
Success
4. 반복문
- while문 보다는 for문을 더 많이 사용한다고 한다.
scores = [90, 85, 77, 65, 97]
cheating_student_list = {2, 4}
for i in range(5):
if i+1 in cheating_student_list:
print(i+1, " student is in cheating student list")
else:
if scores[i] >= 80:
print(i+1, " student passed")
< 출력 >
1 student passed
2 student is in cheating student list
4 student is in cheating student list
5 student passed
5. 함수
- 내장 함수 : 파이썬이 기본적으로 제공하는 함수
- 사용자 정의 함수 : 개발자가 직접 정의하여 사용할 수 있는 함수
def add(a, b):
return a+b
result = add(3,7)
print(result)
< 출력 >
10
- global 변수 : 전역 변수
a = 10
print(a)
def func():
global a
a += 1
func()
print(a)
< 출력 >
10
11
- array는 global 변수 없이도 함수 내에서 참조 가능하다, 하지만 지역 변수의 우선순위가 더 높다
array = [1, 2, 3, 4, 5]
print(array)
def change_func():
array[0] = 100
change_func()
print(array)
< 출력 >
[1, 2, 3, 4, 5]
[100, 2, 3, 4, 5]
- 여러 개의 return 값을 받아올 수 있다.
def operator(a, b):
add_var = a+b
min_var = a-b
mul_var = a*b
div_var = a/b
return add_var, min_var, mul_var, div_var
add, min, mul, div = operator(3, 6)
print(add, min, mul, div)
< 출력 >
9 -3 18 0.5
- 람다 표현식
네 줄의 함수를 람다 함수 표현식으로 간결하게 만들 수 있다.
ⓐ 람다 함수에 매개변수를 주고 싶다면
(lambda 변수 : 식)(매개변수)
ⓑ 람다 함수 내에서는 변수를 만들 수 없다.
윗 줄은 110으로 정확하게 동작하지만,
아랫 줄은 SyntaxError: invalid syntax로 에러가 난다. 즉, lambda 함수 내에서 새로운 변수인 y를 만들 수 없다는 것이다.
ⓒ 람다 표현식은 내장 함수에서 자주 사용된다.
cf) sorted(정렬할 데이터, key 파라미터)
array = [('C', 50), ('F', 32), ('A', 74)]
def my_key(x):
return x[1]
print(sorted(array, key=my_key))
key 값을 x[1]로 주어서 숫자를 기준으로 정렬할 수 있도록 했다.
< 출력 >
[('F', 32), ('C', 50), ('A', 74)]
array = [('C', 50), ('F', 32), ('A', 74)]
print(sorted(array, key=lambda x: x[1]))
< 출력 >
[('F', 32), ('C', 50), ('A', 74)]
list1 = [1, 2, 3, 4, 5]
list2 = [6, 7, 8, 9, 10]
result = map(lambda lst1, lst2: lst1+lst2, list1, list2)
print(list(result))
lamda 함수로 두 리스트의 합을 받아오고 map 함수로 리스트를 재 정의 해준다.
< 출력 >
[7, 9, 11, 13, 15]
6. 실전에서 유용한 표준 라이브러리
(1) 내장 함수 : 기본 입출력 함수부터 정렬 함수까지 기본적인 함수들을 제공(2) itertools : 파이썬에서 반복되는 형태의 데이터를 처리하기 위한 유용한 기능들을 제공 - 순열과 조합(3) heapq : 힙 자료구조를 제공 - 우선순위 큐 기능 구현(4) bisect : 이진 탐색 (binary search) 기능 제공(5) collections : 덱 (deque), 카운터 (counter)(6) math : 필수적인 수학 기능 (팩토리얼, 제곱근, GCD, 삼각함수 관련, 파이)