Statistics/Coding Test
코딩테스트_기초문법.ipynb
해쨔니
2022. 10. 6. 23:08
GitHub - BeBrave-BeHumble/Coding_test
Contribute to BeBrave-BeHumble/Coding_test development by creating an account on GitHub.
github.com
https://www.youtube.com/watch?v=m-9pAwq1o3w&t=5367s
나동빈의 코딩테스트 기초 문법 유튜브 참고
알고리즘 문제 해결 과정
- 지문 읽기 및 컴퓨터적 사고
- 요구사항(복잡도) 분석
- 문제 해결을 위한 아이디어 찾기
- 소스코드 설계 및 코딩
- 일반적으로 대부분의 문제는 핵심 아이디어를 캐치한다면, 간결하게 소스코드를 작성할 수 있는 형태로 출제함. 따라서 문제를 온전히 이해하고 어떻게 코드를 설계할 지 생각하고 풀 것.
- 주 출제 유형
- 그리디 (쉬운 난이도)
- 구현
- DFS/BFS를 활용한 탐색
복잡도
- 시간 복잡도
- 특정한 크기의 입력에 대하여 알고리즘의 수행 시간 분석
- 공간 복잡도
- 특정한 크기의 입력에 대하여 알고리즘의 메모리 사용량 분석
빅오 표기법
가장 빠르게 증가하는 항만을 고려한다. 연산 횟수가 3N^3 + 5N^2 + 1,000,000 인 알고리즘이 있다면 빅오 표기법에서는 차수가 가장 큰 항만 남기므로 O(N^3)으로 표현된다.
O(1) > O(logN) > O(N) > O(NlogN) > O(N^2) > O(N^3) > O(2^n)
알고리즘 설계 Tip
- 연산 횟수가 5억을 넘어가는 경우:
- python기준 5~15초 걸림. C언어보다 오래걸림. pypy가 가장 빠름
- 우선 python으로 제출하고 시간초과 되면 동일한 코드를 pypy로 제출해보기
- 코딩 테스트에서 문제의 시간제한은 통상 1~5초임. 문제에 명시되어 있지 않은 경우 대략 5초라고 생각하기.
- 요구 사항에 따라 적절한 알고리즘 설계하기
- 문제에서 가장 먼저 확인해야 하는 내용은 '시간제한'
- 시간제한이 1초인 문제를 만났을 때, 일반적인 기준
- N의 범위가 500인 경우: 시간 복잡도가 O(N^3)인 알고리즘을 설계
- N의 범위가 2000인 경우: 시간 복잡도가 O(N^2)인 알고리즘을 설계
- N의 범위가 100,000인 경우: 시간 복잡도가 O(NlogN)인 알고리즘을 설계
- N의 범위가 10,000,000인 경우: 시간 복잡도가 O(N)인 알고리즘을 설계
In [1]:
# 시간 복잡도 계산해보기 (1)
array = [3,5,1,2,4] # (N=5)
sum = 0 # 합계 저장할 변수
# 모든 데이터 하나씩 확인하며 합계 계산
for x in array:
sum += x
print(sum)
15
- 수행 시간은 데이터 개수 N에 비례함
- 시간복잡도 : 0(N)
- 시간제한이 1초인 문제를 만났을 때 일반적인 기준
- N의 범위가 500인 경우 : 시간 복잡도가 O(N^3)인 알고리즘을 설계해야 한다.
- N의 범위가 2000인 경우 : 시간 복잡도가 O(N^2)인 알고리즘을 설계해야 한다.
- N의 범위가 100,000인 경우 : 시간 복잡도가 O(NlogN)인 알고리즘을 설계해야 한다.
- N의 범위가 10,000,000인 경우 : 시간 복잡도가 O(N)인 알고리즘을 설계해야 한다.
In [2]:
# 시간 복잡도 계산해보기 (2)
# 2중 for문 이용
array = [3,5,1,2,4] # (N=5)
for i in array:
for j in array:
temp = i * j
print(temp)
9
15
3
6
12
15
25
5
10
20
3
5
1
2
4
6
10
2
4
8
12
20
4
8
16
- 시간복잡도 : 0(N^2)
- 모든 2중 반복문의 시간 복잡도가 N^2인 것은 아님
- 소스코드 내부의 함수의 복잡도까지 고려해야함
수행시간 측청
In [5]:
import time
start_time = time.time()
end_time = time.time()
print('Running time:', end_time - start_time)
Running time: 2.7179718017578125e-05
자료형
정수형(integer)
- 양의 정수, 음의 정수, 0
- 코딩테스트에서 출제되는 많은 문제들은 주로 정수형을 다룸
In [6]:
# 양의 정수
a = 1000
print(a)
# 음의 정수
a = -7
print(a)
# 0
a = 0
print(a)
1000
-7
0
실수형(Real Number)
- float
- 변수에 소수점을 붙인 수를 대입하면 실수형 변수로 처리됨
In [12]:
# 양의 실수
a = 127.56
print(a)
# 음의 실수
a = -127.99
print(a)
# 소수부가 0일 때는 0 생략 가능
a = 408.
print(a)
print(type(a))
# 정수부가 0일 때 0 생략 가능
a = -.408
print(a)
127.56
-127.99
408.0
<class 'float'>
-0.408
지수e 표현 방식
- 유효숫자e지수
- 1e9 = 10^9
- 최단 경로 알고리즘에서는 도달할 수 없는 노드에 대하여 최단 거리를 inf로 설정하곤 함
- 이 때 가능한 최댓값이 10억 미만이라면 inf 값으로 1e9를 사용할 수 있음
In [14]:
a = 1e9
print(a)
a = 75.25e1
print(a)
print(type(a)) # 실수임을 알 수 있음
print(int(a)) # 정수로 하려면 이렇게
a = 345e-8
print(a)
a = 345e8
print(a)
1000000000.0
752.5
<class 'float'>
752
3.45e-06
34500000000.0
실수형 더 알아보기
- 이진수는 0.9같은 값을 실제로 표현하지 못 함
- round 사용하기
- 셋째 자리에서 반올림: round(123.456, 2) = 123.46
In [15]:
a = 0.3+0.6
print(a) # 0.9가 아님을 알 수 있음
if a == 0.9:
print('True')
else:
print('False')
0.8999999999999999
False
In [16]:
round(a, 2) # 둘째자리에서 반올림
Out[16]:
0.9
수 자료형 연산
- 파이썬에서 나누기 연산자(/)는 나눠진 '실수형'으로 반환함!!
- 다양한 로직 설계할 때 나머지 연산자(%) 많이 사용됨
- 예시: a가 홀수인지 체크
- 몫 연산지 (//)
- 거듭제곱 연산자(**)
In [18]:
a = 6
b = 3
# 나누기
print(a / b)
# 나머지
print(a % b)
# 몫
print(a // b)
2.0
0
2
In [23]:
# 거듭제곱
print(a ** b)
# 제곱근 (1)
print(a ** 0.5)
# 제곱근 (2): math 라이브러리 사용
import math
print(math.sqrt(a))
# 제곱근 (3): 세제곱근
print(a ** (1/3))
216
2.449489742783178
2.449489742783178
1.8171205928321397
리스트(List)
- 여러 개의 데이터를 연속적으로 담아 처리하는 자료형
- array랑 비슷하다고 생각하면 됨
- 리스트 초기화
- [] 안에 원소를 넣으면 됨
- 비어있는 인덱스는 list() 혹은 []로 선언
- 리스트의 원소에 접근할 때는 index 사용. (0부터 시작)
In [1]:
# 데이터 직접 넣어 초기화
a = [1, 2, 3, 4]
print(a)
# 네 번째 원소 출력
print(a[3])
# 크기가 N이고, 모든 값이 0인 1차원 리스트
n = 10
a = [0] * n
print(a)
[1, 2, 3, 4]
4
[0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
In [2]:
# 특정 위치 값 바꾸기
a = [1, 2, 3, 4]
a[2] = 7
print(a)
[1, 2, 7, 4]
리스트의 인덱싱과 슬라이싱
- 연속적인 위치를 갖는 원소들을 가져와야 할 때는 슬라이싱 사용
- 끝 인덱스는 실제 인덱스보다 1을 더 크게 설정
In [3]:
# 뒤에서 첫 번째 원소
print(a[-1])
# 뒤에서 세 번째
print(a[-3])
4
2
In [5]:
# 연속적인 위치를 갖는 원소들을 가져와야 할 때는 슬라이싱 사용
# 끝 인덱스는 실제 인덱스보다 1을 더 크게 설정
# 두 번째 원소부터 세 번째 원소까지
print(a)
print(a[1:3])
[1, 2, 7, 4]
[2, 7]
리스트 컴프리헨션
- 리스트를 초기화 하는 방법
- 대괄호 안에 조건문과 반복문을 적용하여 리스트 초기화 할 수 있음
In [6]:
# 0부터 9까지의 수를 포함하는 리스트
a = [i for i in range(10)]
print(a)
print(type(a))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
<class 'list'>
In [7]:
# 0부터 19까지 수 중에서 홀수만 포함하는 리스트
a = [i for i in range(20) if i % 2 == 1]
print(a)
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
In [10]:
# 컴프리헨션 안 쓴 경우
a = [] # 리스트 초기화
for i in range(20):
if i % 2 == 1:
a.append(i)
print(a)
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
In [9]:
# 1부터 9까지 수들의 제곱 값을 포함하는 리스트
a = [i**2 for i in range(1, 10)]
print(a)
[1, 4, 9, 16, 25, 36, 49, 64, 81]
- 2차원 리스트 초기화할 때 효과적으로 사용 가능
- 특히 코딩테스트에서 n*m 크기의 2차원 리스트를 한 번에 초기화 할 때 매우 유용
In [13]:
m = 3
n = 5
array = [[0] * m for _ in range(n)] # _ 대신 알파벳 넣어도 됨~
print(array)
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
In [18]:
# 잘못된 예시 1
a = [[0, 0, 0]*3]
print(a)
# 잘못된 예시 2
a = [[0]*m]*n
print(a)
# 생긴 건 컴프리헨션 사용한 거랑 똑같지만 내부 값들의 id가 다 똑같이 생성됨
# 따라서 전체 리스트 안에 포함된 각 리스트가 모두 같은 객체로 인식됨
a[1] = [7]
print(a)
[[0, 0, 0, 0, 0, 0, 0, 0, 0]]
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
[[0, 0, 0], [7], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
- 컴프리헨션 좋은 예시
In [20]:
m = 3
n = 4
array = [[0] * m for _ in range(n)]
print(array)
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
리스트 컴프리헨션 나쁜 예시
In [21]:
array = [[0] * m ] * n
print(array)
# 4x3 행렬 모양은 제대로 만들어졌지만
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
In [22]:
array[1][1] = 5 # 2행 2열을 5로 변경
print(array) # 2열 전부 5로 변경됨
[[0, 5, 0], [0, 5, 0], [0, 5, 0], [0, 5, 0]]
In [23]:
array[2][0] = 7
print(array) # 3행 1열만 바꾸려 했는데 1열 전부 다 바뀜
[[7, 5, 0], [7, 5, 0], [7, 5, 0], [7, 5, 0]]
- 언더바는 언제 사용하나요?
- 반복문을 수행하되 반복을 위한 변수의 값을 무시하고자 할 때!!
In [28]:
# 1부터 9까지 자연수 더하기
sum = 0
for i in range(1, 10):
sum += i
print(sum)
45
In [30]:
# Hello world! 5번 출력하기
for _ in range(5):
print("hellowordl!")
hellowordl!
hellowordl!
hellowordl!
hellowordl!
hellowordl!
- 리스트 관련 기타 메소드
In [2]:
a = [1, 2, 7]
# 리스트에 원소 삽입
a.append(2)
print('삽입:', a)
# 오름치순 정렬
a.sort()
print('오름차순:', a)
# 내림차순 정렬
a.sort(reverse=True)
print('내림차순:', a)
# 원소 뒤집기
a.reverse()
print('뒤집기:', a)
# 특정 인덱스에 데이터 추가
a.insert(2, 3)
print('인덱스 2에 3추가:', a)
# 특정 값인 데이터 개수 세기
print("값이 3인 데이터 개수:", a.count(a))
# 특정 값 데이터 삭제
a.remove(1)
print('1인 값 삭제:', a)
삽입: [1, 2, 7, 2]
오름차순: [1, 2, 2, 7]
내림차순: [7, 2, 2, 1]
뒤집기: [1, 2, 2, 7]
인덱스 2에 3추가: [1, 2, 3, 2, 7]
값이 3인 데이터 개수: 0
1인 값 삭제: [2, 3, 2, 7]
- 리스트에서 특정 값을 가지는 원소 모두 제거
In [3]:
a = [1, 2, 3 ,4, 5, 5, 5]
remove_set = {3, 5} # 집합 자료형
# remove_set에 포함되지 않은 값만 저장
result = [ i for i in a if i not in remove_set ]
print(result)
# remove는 단순히 원소 하나만을 지우므로 전부를 지울 땐 집합 자료형 이용해야함
[1, 2, 4]
문자열 자료형
- 큰 따옴표나 작은 따옴표 이용
In [4]:
data = 'Hello world!'
print(data)
data = "Don't you know \"Python\"?"
print(data)
Hello world!
Don't you know "Python"?
- 문자열 연산
- 덧셈을 이용하면 문자열이 concat됨
- 양의 정수를 곱하면 문자열이 그 값만큼 여러번 반복됨
- 인덱싱과 슬라이싱 가능하나, 문자열 변경은 불가능
In [7]:
a = "Be Brave"
b = "Be Humble"
print(a + " " + b)
print(a * 3)
print(b[1:5])
Be Brave Be Humble
Be BraveBe BraveBe Brave
e Hu
튜플 자료형
- 리스트와 유사하지만 문법적 차이가 있음
- 한번 선언된 값은 변경 불가능
- 튜플은 소괄호
- 리스트에 비해 상대적으로 기능이 제한적이므로 '공간 효율적' (메모리 작음)
In [8]:
a = (1, 2, 3 ,4 ,5 ,6)
print('네번째 원소:', a[3])
print('슬라이싱:', a[1:4])
네번째 원소: 4
슬라이싱: (2, 3, 4)
In [9]:
a[2] = 7
# 변환 불가능이라 오류
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-9-e6a6e41c76c7> in <module>
----> 1 a[2] = 7
2
3 # 변환 불가능이라 오류
TypeError: 'tuple' object does not support item assignment
튜플을 사용하면 좋은 경우
- 서로 다른 성질의 데이터를 묶어서 관리할 때
- 최단 경로 알고리즘에서 (비용, 노드 번호)의 형태로 튜플 사용
- (이름, 학번) 등
- 데이터의 나열을 해싱(Hashing)의 키 값으로 사용해야 할 때
- 튜플은 변경이 불가능하므로 리스트와 다르게 키 값으로 사용될 수 있음
- 리스트보다 메모리 효율적으로 사용해야 할 때
사전 자료형
- key와 value의 쌍을 데이터로 가지는 자료형
- 앞서 다루었던 리스트나 튜플이 값을 순차적으로 저장하는 것과 대비됨
- key:value를 쌍으로 가지며, 원하는 '변경 불가능한 자료형'을 key로 사용할 수 있음 ex.tuple!!!
- 파이썬에서 자료형은 해시 테이블(Hash Table)을 이용하므로 '데이터 조회 및 수정에 있어서 O(1)의 시간에 처리'할 수 있음
- 문자가 같은 키를 이용하여 데이터를 저장하고 관리할 때 리스트보다 훨씬 효율적으로 조회를 빠르게 수행함
- 키 데이터만 뽑아서 리스트로 이용할 땐 keys() 함수 사용
- 값 데이터만 뽑아서 리스트로 사용할 땐 values() 함수 사용
In [13]:
data = dict() # dict()로 초기화
data['사과'] = 'Apple'
data['바나나'] = 'Banana'
data['코코넛'] = 'Coconut'
print(data)
if '사과' in data: # 특정 키가 있는지 존재하려면 if & in 사용!!!!!!!!
print('"사과"를 키로 가지는 데이터가 존재한다')
{'사과': 'Apple', '바나나': 'Banana', '코코넛': 'Coconut'}
"사과"를 키로 가지는 데이터가 존재한다
In [14]:
# key list
key_list = data.keys()
print(key_list)
value_list = data.values()
print(value_list)
dict_keys(['사과', '바나나', '코코넛'])
dict_values(['Apple', 'Banana', 'Coconut'])
In [17]:
list(data.keys()) # 리스트로 접근하기
Out[17]:
['사과', '바나나', '코코넛']
In [16]:
# 각 키에 따른 값을 하나씩 출력
for key in key_list :
print(data[key])
Apple
Banana
Coconut
집합 자료형
- 중복 허용X
- 순서 없음
- 리스트나 문자열을 이용하여 초기화 가능. set( [] )
- 중괄호 안에 각 원소를 콤마로 구분하여 삽입
- 집합 연산
- 합집합/ 교집합/ 차집합
In [18]:
# 집합 자료형 초기화 방법1
data = set([1,1,1,2,2,2,3,4,5,6,4,2,4,7,8])
print(data)
# 중복 허용 X이므로 한 번씩만 출력됨
{1, 2, 3, 4, 5, 6, 7, 8}
In [19]:
# 집합 자료형 초기화 방법2
data = {1,1,2,3,4,4,5}
print(data)
{1, 2, 3, 4, 5}
In [20]:
a = set([1,2,3,4,5])
b = set([3,4,5,3,1])
# 합집합
print(a|b)
# 교집합
print(a&b)
# 차집합
print(a-b)
{1, 2, 3, 4, 5}
{1, 3, 4, 5}
{2}
In [21]:
# 새로운 원소 추가 : add
data.add(4)
print(data)
# 새로운 원소 여러개 추가: update
data.update([10,11])
print(data)
# 특정한 값을 갖는 원소 삭제
data.remove(3)
print(data)
{1, 2, 3, 4, 5}
{1, 2, 3, 4, 5, 10, 11}
{1, 2, 4, 5, 10, 11}
사전 자료형과 집합 자료형 특징
- 리스트나 튜플과 달리 순서가 없기 때문에 인덱싱으로 값 얻을 수 x
- 사전의 key 혹은 집합의 원소를 이용해 O(1)의 시간 복잡도
기본 입출력
- input 함수는 한 줄의 문자열을 입력받는 함수
- map함수는 리스트의 모든 원소에 각각 특정한 함수를 적용하고자 할 때 사용
- 예시) 공백 기준으로 구분된 데이터 입력 받을 때
- list( map( int, input().split() ) )
- 예시) 공백 기준으로 구분된 데이터 수가 많지 않다면 다음처럼 사용
- a, b, c = map( int, input().split() )
입력을 위한 전형적인 소스코드 1
In [ ]:
# 데이터의 개수 입력
n = int(input())
# 각 데이터를 공백 기준으로 구분하여 입력
data = list( map( int, input().split() ))
data.sort(reverse=True) # 내림차순
print(data)
In [23]:
# 실습
n = int(input()) # 데이터 수 입력
data = input() # 데이터 값 입력
print(n)
print(data)
5
78 94 32 85 43
5
In [25]:
n = int(input())
data = input().split() # 공백기준으로 분리하겠다
print(n)
print(data) # 공백 기준으로 문자열이 분리됨
5
87 23 11 56 77
5
['87', '23', '11', '56', '77']
In [26]:
# 실제 코테에선 이렇게 가장 많이 씀!!!!
# 문제 초반부 입력 받는 부분에 이렇게 할 것~!~!
n = int(input())
data = list(map( int, input().split() )) # 정수형 함수 적용하여 리스트에 넣기
print(n)
print(data)
5
22 34 54 11 66
5
[22, 34, 54, 11, 66]
In [27]:
# 반드시 데이터가 세개가 들어온다고 정해져있다면
a, b, c = map(int, input().split()) # 언패킹 = 패킹
print(a,b,c)
44 92 77
44 92 77
빠르게 입력 받기
- 입력의 수가 많은 경우, 최대한 빠르게 받아서 씀
- 이진탐색, 정렬, 그래프 문제에서 씀
- 파이썬의 경우 sys라이브러리에 정의된 sys.stdin.readline() 메서드 이용
- 단, 입력 후 엔터가 줄 바꿈 기호로 입력되므로 'rstrip()' 함께 써야함!!!
In [28]:
import sys
# 문자열 입력받기
data = sys.stdin.readline().rstrip()
print(data)
출력을 위한 전형적인 소스코드
In [29]:
a = 1
b = 2
print(a, b) # print 후에는 자동으로 줄바꿈 됨
print(7, end=" ") # 줄바꿈 대신 스페이스 사용하면 밑의 8과 한줄로 붙어서 공백으로 분리되어 출력됨
print(8, end=" ")
dd = 7
print("정답은 " + str(dd) +"입니다.")
1 2
7 8 정답은 7입니다.
f-string 예제
- 문자열 앞에 f를 붙여 사용함
- 중괄호 안에 변수명 기입하여 간단히 문자열과 정수 함께 넣을 수 있음
In [30]:
# 문자열 앞에 f를 붙여 사용함
dd = 7
print(f"정답은 {dd}입니다.")
정답은 7입니다.
조건문
- 프로그램의 흐름을 제어
In [32]:
a = 5
if a >= 0:
print("a>=0")
elif a >= -10:
print("0> a> -10")
else:
print("-10>a")
print("종료.")
a>=0
종료.
조건문 간소화
- 조건문에서 실행할 소스코드가 한 줄인 경우 사용
In [41]:
score = 85
if score >= 80: result = "success"
else: result = "fail"
print(result)
success
- 조건부 표현식은 if~else 문을 한 줄에 작성할 것!
In [42]:
score = 85
result = "success" if score >= 80 else "fail" # if 기준 참일 때가 왼쪽 거짓일 때가 오른쪽
print(result)
success
논리 연산자
- A and B
- A or B
- not A
In [35]:
a = 15
if a <= 20 and a >= 0:
print("yes")
yes
In [36]:
# 조건문 내부에서는 수학 부등식 사용 가능
if 0 <= a <= 20:
print("yes")
yes
기타 연산자
- 리스트, 튜플, 문자열, 딕셔너리 모두 사용 가능
- x in 리스트
- x not in 문자열
pass 키워드
- 아무것도 처리하고 싶지 않을 때 사용
- 일단 조건문 형태만 만들고 조건문 처리 과정 비우고 싶은 경우 사용
In [39]:
score = 85
if score >= 80:
pass # 나중에 처리할 부분
else:
print("a<30")
반복문
- 특정한 소스코드 반복 실행
- while, for 아무거나 사용 가능하나 보통 코테에서는 for가 더 간결함
while
1부터 9까지 모든 정수 합 구하는 예제
In [44]:
i = 1
result = 0
while i <= 9:
result += i
i += 1
print(result)
45
1부터 9까지 홀수 합 구하기
In [48]:
i = 1
result = 0
while i < 10:
if i % 2 == 1:
result += i
i += 1
print(result)
25
for
In [49]:
array = [1, 23, 4, 56]
for x in array:
print(x)
1
23
4
56
continue 키워드
- 남은 코드의 실행을 건너뛰고, 다음 반복 진행할 때 사용
In [51]:
# 1부터 9까지 홀수의 합
result = 0
for i in range(1, 10):
if i % 2 == 0:
continue
# result -= 1
result += i
print(result)
25
break 키워드
- 반복문 즉시 탈출
In [53]:
# 1부터 5까지 정수 차례로 입력
i = 1
while True:
print("현재 i 값", i)
if i >= 5:
break
i += 1
현재 i 값 1
현재 i 값 2
현재 i 값 3
현재 i 값 4
현재 i 값 5
반복문 예제
In [54]:
# 1) 학생들의 점수가 80점 넘으면 합격
score = [90, 85, 77, 65, 97]
for i in score:
if i >= 80:
print(f"{i}점 이므로 합격")
else:
print(f"{i}점 이므로 불합격")
90점 이므로 합격
85점 이므로 합격
77점 이므로 불합격
65점 이므로 불합격
97점 이므로 합격
In [57]:
aa = [print(i+1, "번 학생 합격") for i in range(5) if score[i]>80]
1 번 학생 합격
2 번 학생 합격
5 번 학생 합격
In [58]:
# 2) 부정학생 제외하기
cheating_list = {2, 4}
for i in range(5):
if i+1 in cheating_list:
continue
if score[i] >= 80:
print(i+1, "번 학생은 합격입니다")
1 번 학생은 합격입니다
5 번 학생은 합격입니다
In [62]:
# 2) 이중포문: 구구단 예제
for i in range(2, 10):
for j in range(1, 10):
print(i, '*', j, "=", i*j )
print()
2 * 1 = 2
2 * 2 = 4
2 * 3 = 6
2 * 4 = 8
2 * 5 = 10
2 * 6 = 12
2 * 7 = 14
2 * 8 = 16
2 * 9 = 18
3 * 1 = 3
3 * 2 = 6
3 * 3 = 9
3 * 4 = 12
3 * 5 = 15
3 * 6 = 18
3 * 7 = 21
3 * 8 = 24
3 * 9 = 27
4 * 1 = 4
4 * 2 = 8
4 * 3 = 12
4 * 4 = 16
4 * 5 = 20
4 * 6 = 24
4 * 7 = 28
4 * 8 = 32
4 * 9 = 36
5 * 1 = 5
5 * 2 = 10
5 * 3 = 15
5 * 4 = 20
5 * 5 = 25
5 * 6 = 30
5 * 7 = 35
5 * 8 = 40
5 * 9 = 45
6 * 1 = 6
6 * 2 = 12
6 * 3 = 18
6 * 4 = 24
6 * 5 = 30
6 * 6 = 36
6 * 7 = 42
6 * 8 = 48
6 * 9 = 54
7 * 1 = 7
7 * 2 = 14
7 * 3 = 21
7 * 4 = 28
7 * 5 = 35
7 * 6 = 42
7 * 7 = 49
7 * 8 = 56
7 * 9 = 63
8 * 1 = 8
8 * 2 = 16
8 * 3 = 24
8 * 4 = 32
8 * 5 = 40
8 * 6 = 48
8 * 7 = 56
8 * 8 = 64
8 * 9 = 72
9 * 1 = 9
9 * 2 = 18
9 * 3 = 27
9 * 4 = 36
9 * 5 = 45
9 * 6 = 54
9 * 7 = 63
9 * 8 = 72
9 * 9 = 81
함수
- 매개변수: 함수 내부에서 쓸 변수
- 반환 값: 처리된 결과 반환
def 함수명(매개변수):
실행할 소스코드
return 반환값
- 더하기 함수 예시 1)
In [63]:
def add(a,b):
return a+b
print(add(3,7)) # 함수 안에 넣는 값은 arguments, 인자라고 함
10
- 더하기 함수 예시 2)
In [65]:
def add(a,b):
print('함수 결과:', a+b)
add(3,6)
# 이렇게 꼭 return이 없어도 됨
함수 결과: 9
파라미터 지정하기
In [66]:
def add(a,b):
return a+b
print(add(b=3,a=7))
10
global 키워드
- global 키워드로 변수를 지정하면 해당 함수에서는 지역 변수를 만들지 않고, 함수 바깥에 선언된 변수를 바로 참조함
- 하지만 함수 안에 지역변수 선언하면 지역변수 우선임
In [ ]:
a = 0
def func():
global a
a += 1
for i in range(10):
func()
print(a)
In [69]:
a = 10
def func():
global a
a += 1 # 가져온 값을 바꾸려면 위에 global 선언해야함
print(a)
func()
11
In [70]:
a = 10
def func():
print(a) # 함수에 변환 안 할거면 선언 안 해도 됨
func()
10
In [72]:
array = [1,2,3,4,5] # 리스트도 전역 변수로 사용 가능
def func():
array.append(99) # 그러나 리스트의 경우 따로 global 선언 안 해도 값 바꿀 수 있음
print(array)
func()
[1, 2, 3, 4, 5, 99]
In [73]:
array = [1,2,3,4,5] # 리스트도 전역 변수로 사용 가능
def func():
global array
array = [3, 4, 5] # 글로벌 선언 해놓고 내부에서 값을 바꾸면
array.append(99)
print(array)
func()
print(array) # 전역변수 또한 내부에서 선언한대로 바뀜
[3, 4, 5, 99]
[3, 4, 5, 99]
여러개의 반환값
- 컴마로 구분지어서 반환값을 여러개 리턴할 수 있음 => 패킹
In [75]:
def operator(a, b):
add_var = a + b
substract_var = a - b
multiply_var = a * b
divide_Var = a / b
return add_var, substract_var, multiply_var, divide_Var # 패킹하여 반환
print(operator(7,3))
a, b, c, d = operator(7,3) # 언패킹하여 반환
print(a, b, c, d)
(10, 4, 21, 2.3333333333333335)
10 4 21 2.3333333333333335
람다 표현식
- 람다 표현식 이용하면 함수 간단 작성 가능
- 특정한 기능을 수행하는 함수를 한 줄에 작성할 수 있음
- 함수의 이름을 요구하지 않음
- 매개변수를 차례로 입력하고, 콜론, 함수
- 함수 자체를 입력으로 받는 또 다른 함수에서 유용함 (내장함수)
In [76]:
# 람다로 구현한 add
print( (lambda a, b : a + b)(3, 7))
10
- 람다 표현식 예시: 내장 함수에서 자주 사용되는 람다 함수
In [77]:
array = [('해찬', 00), ('도영', 96), ('재현', 97)]
def my_key(x):
return x[1] # 두 번째 원소
print(sorted(array, key = my_key)) # sorted(정렬할 리스트, 기준)
print(sorted(array, key = lambda x: x[1]))
[('해찬', 0), ('도영', 96), ('재현', 97)]
[('해찬', 0), ('도영', 96), ('재현', 97)]
- 람다 표현식 예시: 여러 개의 리스트에 적용
In [82]:
# 여러개의 리스트에 동일한 규칙 적용할 때
list1 = [1, 2, 3, 4, 5]
list2 = [6, 7, 8, 9, 10]
# map: 각 원소에 어떤 함수 적용할 때.
# 첫 번째 원소끼리/ 두 번째 원소 끼리,,,, 를 더한 결과를 리스트에 담을 때
result = map(lambda a, b: a + b, list1, list2) # 람다함수 정의, 각 원소를 뽑아낼 리스트 정의
print(list(result))
print(result)
[7, 9, 11, 13, 15]
<map object at 0x7f72225e70d0>
실전에서 유용한 표준 라이브러리
- 내장함수: 기본 입출력부터 정렬까지
- itertools: 파이썬에서 반복되는 형태의 데이터 처리하기 위한 기능 제공
- 특히 순열과 조합 라이브러리는 코딩 테스트에 자주 사용됨. (모든 경우를 탐색해야 하는 경우)
- heapq: 힙(Heap) 자료구조 제공
- 일반적으로 우선순위 큐 기능 구현하기 위해 사용됨. 최단 경로에 응용
- bisect: 이진탐색 (binary search) 기능 제공
- collections: 덱(deque), 카운터(counter) 등의 유용한 자료 구조를 포함함
- math: 필수적인 수학 기능 제공
- 팩토리얼, 제곱근, 최대공약수(GCD), 삼각함수, 파이(pi)
내장함수
In [86]:
array = [1, 2, 3, 4, 5]
# sum
print(sum(array))
# min, max
print(min(array), max(array))
# eval() : 수식을 계산한 결과를 수 형태로 반환
result = eval("(3+5)*7")
print(result)
15
1 5
56
- 새로운 정렬된 리스트를 반환하는 함수는 sorted 함수
- 리스트 자체를 정렬 시키는 것은 sort 함수
In [94]:
# sorted
print(sorted(array))
print(sorted(array, reverse=True))
import math
array.sort
print(array) # 원본 값이 바뀜
array.sort(reverse=True)
print(array)
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]
[1, 2, 3, 4, 5]
[5, 4, 3, 2, 1]
In [95]:
# sorted with key
array = [('해찬', 00), ('도영', 96), ('재현', 97)]
result = sorted(array, key = lambda x: x[1], reverse = True)
print(result)
[('재현', 97), ('도영', 96), ('해찬', 0)]
순열과 조합
- 순열: nPr 일렬로 나열. 순서를 고려함
- 조합: nCr 순서에 상관없이 서로 다른 r개 뽑기
In [98]:
# 순열
from itertools import permutations
data = ['해찬', '도영', '재현']
result = list(permutations(data, 3)) # 세개 뽑아서 모든 순열 구하기
print(result)
[('해찬', '도영', '재현'), ('해찬', '재현', '도영'), ('도영', '해찬', '재현'), ('도영', '재현', '해찬'), ('재현', '해찬', '도영'), ('재현', '도영', '해찬')]
In [100]:
# 조합
from itertools import combinations
data = ['해찬', '도영', '재현']
result = list(combinations(data, 2))
print(result)
[('해찬', '도영'), ('해찬', '재현'), ('도영', '재현')]
중복순열과 중복조합
In [102]:
from itertools import product
data = ['해찬', '도영', '재현']
result = list(product(data, repeat=2)) # 2개 뽑는 모든 순열 구하기 (중복 허용)
print(result)
from itertools import combinations_with_replacement
result = list(combinations_with_replacement(data, 2)) # 중복 허용하여 2개 뽑기
print(result)
[('해찬', '해찬'), ('해찬', '도영'), ('해찬', '재현'), ('도영', '해찬'), ('도영', '도영'), ('도영', '재현'), ('재현', '해찬'), ('재현', '도영'), ('재현', '재현')]
[('해찬', '해찬'), ('해찬', '도영'), ('해찬', '재현'), ('도영', '도영'), ('도영', '재현'), ('재현', '재현')]
Counter
- 각 원소의 등장 횟수를 세는 기능!!!!!!!!!!!!!!
- 리스트와 같은 반복 가능한 객체 주어졌을 때 내부 원소가 몇 번 등장했는지 알려줌
In [103]:
from collections import Counter
counter = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])
print(counter['blue'])
print(counter['green'])
print(dict(counter)) # 사전 자료형으로 반환
3
1
{'red': 2, 'blue': 3, 'green': 1}
최대공약수와 최소공배수
In [104]:
import math
# 최소공배수(LCM)
def lcm(a, b):
return a * b // math.gcd(a, b) # 최소공배수 공식에 따라 최대공약수로 나눈 결과값 리턴
a = 21
b = 14
print(math.gcd(21, 14)) # 최대 공약수
print(lcm(21, 14)) # 최소 공배수
7
42
In [ ]:
In [ ]:
In [ ]:
In [ ]: