ETC/기타

[Python] 코딩테스트 대비 잊기 쉬운 기본 지식 총정리

지과쌤 2021. 10. 14.
반응형

출처 - 이코테 2021


빅오 표기법(Big-O Notation)

- 가장 빠르게 증가하는 항 만을 고려한 표기법 : 함수의 상한만을 나타낸다.

- 3n^3 + 5n^2 + 1000000 인 알고리즘은 O(n^3)으로 표현됨.


알고리즘 설계 팁

- 일반적으로 CPU 기반의 개인 컴퓨터나 채점용 컴퓨터에서 연산 횟수가 5억을 넘어가는 경우 :

    - C언어를 기준으로 통상 1 ~ 3초 가량의 시간이 소요

    - Python을 기준으로 통상 5 ~ 15초 가량의 시간이 소요

        - PyPy의 경우 때때로 C언어보다도 빠르게 동작하기도 함!

 

- O(n^3)의 알고리즘의 경우, N의 값이 5000이 넘는다면 약 1250억정도...

    - 파이썬은 1초에 약 5천만번정도 계산이 가능 -> 약 2500초정도 걸림(?!)

 

따라서 어느정도 수행시간을 예측하며 알고리즘을 짜는것이 중요하다.

특히 채점용 서버에서는 파이썬이 1초에 약 2천만번정도 연산이 가능하다고 가정하고 문제에 접근하는것이 좋다..

통상적으로 코딩 테스트에서 시간제한은 1 ~ 5초정도라고 생각하는것이 합리적.


요구사항에 따라 적절한 알고리즘 설계하기

- 문제에서 가장 먼저 확인해야 하는 내용은 시간제한(수행시간 요구사항).

- 시간제한이 1초인 문제를 만났을 때, 일반적인 기준

 

    - N의 범위가 500인 경우 : 시간 복잡도가 O(n^3)인 알고리즘을 설계하면 문제를 풀 수 있다.

    - N의 범위가 2,000인 경우 : 시간 복잡도가 O(n^2)인 알고리즘을 설계하면 문제를 풀 수 있다.

    - N의 범위가 100,000인 경우 : 시간 복잡도가 O(nlogn)인 알고리즘을 설계하면 문제를 풀 수 있다.

    - N의 범위가 10,000,000인 경우 : 시간 복잡도가 O(n)인 알고리즘을 설계하면 문제를 풀 수 있다.


일반적인 알고리즘 문제 해결 과정

1. 지문 읽기 및 컴퓨터적 사고

2. 요구사항(복잡도) 분석

3. 문제 해결을 위한 아이디어 찾기

4. 소스코드 설계 및 코딩

 

- 일반적으로 대부분의 문제 출제자들은 핵심 아이디어를 캐치한다면, 간결하게 소스코드를 작성할 수 있는 형태로 문제를 출제한다. -> 소스코드를 작성하기 전 핵심 아이디어를 캐치하자!


수행 시간 측정 소스코드 예제

import time
start_time = time.time() #측정 시작

#프로그램 소스코드

end_time = time.time()
print("time:", end_time - start_time) #수행 시간 출력

지수 표현 방식

- 파이썬에서는 e나 E를 이용한 지수 표현 방식을 이용할 수 있다.

    - e나 E 다음에 오는 수는 10의 지수부를 의미한다.

    - 예를 들어 1e9 라고 입력하게 되면, 10의 9제곱(1,000,000,000)이 된다.

- 지수 표현 방식은 임의의 큰 수를 표현하기 위해 자주 사용된다

- 최단 경로 알고리즘에서는 도달할 수 없는 노드에 대하여 최단 거리를 무한(INF)로 설정하곤 한다.

- 이때 가능한 최댓값이 10억 미만이라면 무한(INF)의 값으로 1e9를 이용할 수 있다.

# 1,000,000,000
a = 1e9
print(a)

# 752.5
a = 75.25e1
print(a)

# 3.954
a = 3954e-3
print(a)

1e9같은경우 실수이므로 int()를 사용해 정수로 바꾸어주는것도 필요하다.


실수형 더 알아보기

- 오늘날 가장 널리 쓰이는 IEEE754 표준에서는 실수형을 저장하기 위해 4바이트, 혹은 8바이트의 고정된 크기의 메모리를 할당하므로, 컴퓨터 시스템은 실수 정보를 표현하는 정확도에 한계를 가진다.

- 예를 들어 10진수 체계에서는 0.3과 0.6을 더한 값이 0.9로 정확히 떨어진다.

    - 하지만 2진수에서는 0.9를 정확히 표현할 수 있는 방법이 없다

    - 컴퓨터는 최대한 0.9와 가깝게 표현하지만, 미세한 오차가 발생하게 된다.

a = 0.3 + 0.6
print(a)

if a == 0.9:
    print(True)
else:
    print(False)
    
# 실행 결과
# 0.8999999999999999
# False

 

- 개발 과정에서 실수 값을 제대로 비교하지 못해서 원하는 결과를 얻지 못할 수 있다.

- 이럴 때는 round() 함수를 이용할 수 있으며, 이러한 방법이 권장된다.

- 예를 들어 123.456을 소수 셋째 자리에서 반올림하려면 round(123.456, 2)라고 작성한다.

    - 결과는 123.46이 된다.


수 자료형의 연산

- 파이썬에서 나누기 연산자(/)는 나눠진 결과를 실수형으로 반환한다.

- 나머지 연산자(%)도 이용하면 좋다. - 특정 값이 홀수인지 체크해야 하는 경우

- 파이썬에서는 몫을 얻기 위해 몫 연산자(//)를 사용한다.

- 이외에도 거듭 제곱 연산자(**)를 비롯해 다양한 연산자들이 존재한다.


리스트의 인덱싱과 슬라이싱

- 파이썬의 인덱스 값은 정수와 음의 정수를 모두 사용할 수 있다.

- 음의 정수를 넣으면 원소를 거꾸로 탐색하게 된다.

- 리스트에서 연속적인 위치를 갖는 원소들을 가져와야 할 때는 슬라이싱을 이용한다.

    - 대괄호 안에 콜론(:)을 넣어서 시작 인덱스와 끝 인덱스를 설정할 수 있다.

    - 끝 인덱스는 실제 인덱스보다 1을 더 크게 설정한다.


리스트 컴프리헨션

- 리스트를 초기화하는 방법 중 하나

    - 대괄호 안에 조건문과 반복문을 적용하여 리스트를 초기화 할 수 있다.

# 0부터 9까지의 수를 포함하는 리스트
array = [i for i in range(10)]

print(array)

# 실행 결과
# [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
# 0부터 19까지의 수 중에서 홀수만 포함하는 리스트
array = [i for i in range(20) if i % 2 == 1]

print(array)

# 1부터 9까지의 수들의 제곱 값을 포함하는 리스트
array = [i * i for i in range(1, 10)]

print(array)

# 실행 결과
# [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
# [1, 4, 9, 16, 25, 36, 49, 64, 81]

- 리스트 컴프리헨션은 2차원 리스트를 초기화할 때 효과적으로 사용될 수 있다.

- 특히 N * M 크기의 2차원 리스트를 한 번에 초기화 해야 할 때 매우 유용하다.

    - 좋은 예시 : array = [[0] * m for _ in range(n)]

- 만약 2차원 리스트를 초기화할 때 다음과 같이 작성하면 예기치 않은 결과가 나올 수 있다.

    - 잘못된 예시 : array = [[0] * m] * n

    - 위 코드는 전체 리스트 안에 포함된 각 리스트가 모두 같은 객체로 인식된다.

   

- 파이썬은 기본적으로 리스트 자료형을 이용해서 어떠한 변수값을 할당하게 되면 내부적으로 그 리스트는 객체형태로 처리가 되고, 별도의 주소값을 가지게 된다. 따라서 단순히 어떤 리스트 자체를 n번 곱하게 되면 리스트의 참조값을 n번 복사하는것과 같기 때문에 내부 리스트들이 모두 같은 객체로 인식된다. 따라서 하나의 값만 바꾸더라도 다른 값들이 동시에 바뀌게 된다!


리스트 컴프리헨션 (좋은 예시)

# N * M 크기의 2차원 리스트 초기화
n = 4
m = 3
array = [[0] * m for _ in range(n)]
print(array)

# 실행 결과
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]

리스트 컴프리헨션 (잘못된 예시)

# N * M 크기의 2차원 리스트 초기화 (잘못된 방법)
n = 4
m = 3
array = [[0] * m] * n
print(array)

array[1][1] = 5
print(array)

# 실행 결과
# [[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, 0]]
# [[0, 5, 0], [0, 5, 0], [0, 5, 0], [0, 5, 0]]


리스트 관련 기타 메서드

코딩테스트에서 많이 사용되는 함수

함수명 사용법 설명 시간 복잡도
append() 변수명.append() 리스트에 원소를 하나 삽입할 때 사용한다. O(1)
sort() 변수명.sort() 기본 정렬 기능으로 오름차순으로 정렬한다 O(NlogN)
변수명.sort(reverse = True) 내림차순으로 정렬한다.
reverse() 변수명.reverse() 리스트의 원소의 순서를 모두 뒤집어 놓는다. O(N)
insert() insert(삽입할 위치 인덱스, 삽입할 값) 특정한 인덱스 위치에 원소를 삽입할 때 사용한다. O(N)
count() 변수명.count(특정 값) 리스트에서 특정한 값을 가지는 데이터의 개수를 셀 때 사용한다. O(N)
remove() 변수명.remove(특정 값) 특정한 값을 갖는 원소를 제거하는데, 값을 가진 원소가 여러 개면 하나만 제거한다. O(N)

리스트에서 특정 값을 가지는 원소를 모두 제거하기

- 집합 자료형 사용 : 특정한 원소의 존재 유무만을 체크하고자 할 때 매우 효과적으로 사용가능

a = [1, 2, 3, 4, 5, 5, 5]
remove_set = {3, 5}

# remove_list에 포함되지 않은 값만을 저장
result = [i for i in a if i not in remove_set]
print(result)

# 실행 결과
# [1, 2, 4]

문자열 자료형

- 문자열 변수를 초기화할 때는 큰따옴표(")나 작은 따옴표(')를 이용.

- 문자열 안에 큰따옴표나 작은따옴표가 포함되어야 하는 경우가 있다.

    - 전체 문자열을 큰따움표로 구성하는 경우, 내부적으로 작은따옴표를 포함할 수 있다.

    - 전체 문자열을 작은따옴표로 구성하는 경우, 내부적으로 큰따옴표를 포함할 수 있다.

    - 혹은 백슬래시(\)를 사용하면, 큰따옴표나 작은따옴표를 원하는 만큼 포함시킬 수 있다.


문자열 연산

- 문자열 변수에 덧셈(+)을 이용하면 문자열이 더해져서 연결된다.

- 문자열 변수를 특정한 양의 정수와 곱하는 경우, 문자열이 그 값만큼 여러 번 더해진다.

- 문자열에 대해서도 마찬가지로 인덱싱과 슬라이싱을 이용할 수 있다.

    - 다만 문자열은 특정 인덱스의 값을 변경할 수는 없다. (Immutable)


튜플 자료형

- 튜플 자료형은 리스트와 유사하지만 다음과 같은 문법적 차이가 있다.

    - 튜플은 한 번 선언된 값을 변경할 수 없다.

    - 리스트는 대괄호([])를 이용하지만, 튜플은 소괄호(())를 이용한다.

- 튜플은 리스트에 비해 상대적으로 공간 효율적이다.

튜플을 사용하면 좋은 경우

- 서로 다른 성질의 데이터를 묶어서 관리해야 할 때

    - 최단 경로 알고리즘에서는 (비용, 노드 번호) 의 형태로 튜플 자료형을 자주 사용한다.

- 데이터의 나열을 해싱(Hashing)의 키 값으로 사용해야 할 때

    - 튜플은 변경이 불가능하므로 리스트와 다르게 키 값으로 사용될 수 있다.

    - 리스트는 변경가능하므로 해싱의 키값으로 사용 불가능

- 리스트보다 메모리를 효율적으로 사용해야 할 때


사전 자료형

- 사전 자료형은 키(Key)와 값(Value)의 쌍을 데이터로 가지는 자료형이다.

    - 앞서 다루었던 리스트나 튜플이 값을 순차적으로 저장하는 것과는 대비된다.

- 사전 자료형은 키와 값의 쌍을 데이터로 가지며, 원하는 '변경 불가능한(Immutable) 자료형'을 키로 사용할 수 있다.

- 파이썬의 사전 자료형은 해시 테이블(Hash Table)을 이용하므로 데이터의 조회 및 수정에 있어서 O(1)의 시간에 처리할 수 있다.

data = dict()
data['사과'] = 'Apple'
data['바나나'] = 'Banana'
data['코코넛'] = 'Coconut'

print(data)

if '사과' in data:
    print("'사과'를 키로 갖는 데이터가 존재합니다.")
    
# 실행 결과
# {'사과': 'Apple', '바나나': 'Banana', '코코넛': 'Coconut'}
# '사과'를 키로 갖는 데이터가 존재합니다.

사전 자료형 관련 메서드

- 사전 자료형에서는 키와 값을 별도로 뽑아내기 위한 메서드를 지원한다.

    - 키 데이터만 뽑아서 리스트로 이용할 때는 keys() 함수를 이용한다.

    - 값 데이터만을 뽑아서 리스트로 이용할 때는 values() 함수를 이용한다.

data = dict()
data['사과'] = 'Apple'
data['바나나'] = 'Banana'
data['코코넛'] = 'Coconut'

# 키 데이터만 담은 리스트
key_list = data.keys()
# 값 데이터만 담은 리스트
value_list = data.values()
print(key_list)
print(value_list)

# 각 키에 따른 값을 하나씩 출력
for key in key_list:
    print(data[key])
    
# 실행 결과
# dict_keys(['사과', '바나나', '코코넛'])
# dict_values(['Apple', 'Banana', 'Coconut'])
# Apple
# Banana
# Coconut

집합 자료형

- 집합은 다음과 같은 특징이 있다

    - 중복을 허용하지 않는다.

    - 순서가 없다.

- 집합은 리스트 혹은 문자열을 이용해서 초기화할 수 있다.

    - 이때 set() 함수를 이용한다.

- 혹은 중괄호({})안에 각 원소를 콤마(,)를 기준으로 구분하여 삽입함으로써 초기화 할 수 있다.

- 데이터의 조회 및 수정에 있어서 O(1)의 시간에 처리할 수 있다.

집합 자료형의 연산

a = set([1, 2, 3, 4, 5])
b = set([3, 4, 5, 6, 7])

# 합집합
print(a | b)

# 교집합
print(a & b)

# 차집합
print(a - b)

# 실행 결과
# {1, 2, 3, 4, 5, 6, 7}
# {3, 4, 5}
# {1, 2}

집합 자료형 관련 함수

data = set([1, 2, 3])
print(data)

# 새로운 원소 추가
data.add(4)
print(data)

# 새로운 원소 여러 개 추가
data.update([5, 6])
print(data)

# 특정한 값을 갖는 원소 삭제
data.remove(3)
print(data)

# 실행 결과
# {1, 2, 3}
# {1, 2, 3, 4}
# {1, 2, 3, 4, 5, 6}
# {1, 2, 4, 5, 6}

사전 자료형과 집합 자료형의 특징

- 리스트나 튜블은 순서가 있기 때문에 인덱싱을 통해 자료형의 값을 얻을 수 있다.

- 사전 자료형과 집합 자료형은 순서가 없기 때문에 인덱싱으로 값을 얻을 수 없다.

    - 사전의 키(key) 혹은 집합의 원소(element)를 이용해 O(1)의 시간 복잡도로 조회한다.


자주 사용되는 표준 입력 방법

input() 함수는 한 줄의 문자열을 입력 받는 함수이다.

map() 함수는 리스트의 모든 원소에 각각 특정한 함수를 적용할 때 사용한다.

 

예시) 공백을 기준으로 구분된 데이터를 입력 받을 때는 다음과 같이 사용한다.

    - list(map(int, input().split()))

예시) 공백을 기준으로 구분된 데이터의 개수가 많지 않다면, 단순히 다음과 같이 사용한다.

    - a, b, c = map(int, input().split())

빠르게 입력 받기

- 사용자로부터 입력을 최대한 빠르게 받아야 하는 경우가 있다.

- 파이썬의 경우 sys 라이브러리에 정의되어 있는 sys.stdin.readline() 메서드를 이용한다.

    - 단, 입력 후 엔터(Enter)가 줄 바꿈 기호로 입력되므로 rstrup() 메서드를 함께 사용한다.

- 이진탐색, 정렬 그래프 문제에서 자주 사용됨.

import sys

# 문자열 입력 받기
data = sys.stdin.readline().rstrip()
print(data)

자주 사용되는 표준 출력 방법

- 파이썬에서 기본 출력은 print() 함수를 이용한다.

    - 각 변수를 콤마(,)를 이용하여 띄어쓰기로 구분하여 출력할 수 있다.

- print()는 기본적으로 출력 이후에 줄 바꿈을 수행한다.

    - 줄 바꿈을 원치 않는 경우 'end' 속성을 이용할 수 있다.

# 출력할 변수들
a = 1
b = 2
print(a, b)
print(7, end=" ")
print(8, end=" ")

# 출력할 변수
answer = 7
print("정답은 " + str(answer) + "입니다.")

# 실행 결과
# 1 2
# 7 8 정답은 7입니다.

f-string 예제

- 파이썬 3.6부터 사용 가능하며, 문자열 앞에 접두사 'f'를 붙여 사용한다.

- 중괄호 안에 변수명을 기입하여 간단히 문자열과 정수를 함께 넣을 수 있다.

answer = 7
print(f"정답은 {answer}입니다.")

# 실행 결과
# 정답은 7입니다.

파이썬의 기타 연산자

- 다수의 데이터를 담는 자료형을 위해 in 연산자와 not in 연산자가 제공된다.

    - 리스트, 튜플, 딕셔너리 모두 사용 가능

in 연산자와 not in 연산자 설명
x in 리스트 리스트 안에 x가 들어가 있을 때 참(True)이다.
x not in 문자열 문자열 안에 x가 들어가 있지 않을 때 참(True)이다.

파이썬의 pass 키워드

- 아무것도 처리하고 싶지 않을 때 pass 키워드를 사용한다.

예시) 디버깅 과정에서 일단 조건문의 형태만 만들어 놓고 조건문을 처리하는 부분은 비워놓고 싶은 경우

score = 85

if score >= 80:
    pass # 나중에 작성할 소스코드
else:
    print("성적이 80점 미만입니다.")

print("프로그램을 종료합니다.")

# 실행 결과
# 프로그램을 종료합니다

조건문의 간소화

- 조건문에서 실행될 소스코드가 한 줄인 경우, 굳이 줄 바꿈을 하지 않고도 간략하게 표현할 수 있다.

score = 85

if score >= 80: result = "Success"
else: result = "Fail"

# 실행 결과
# Success

- 조건부 표현식(Conditional Expression)은 if ~ else문을 한 줄에 작성할 수 있도록 해준다.

score = 85
result = "Success" if score >= 80 else "Fail"

print(result)

# 실행 결과
# Success

파이썬의 continue 키워드

- 반복문에서 남은 코드의 실행을 건너뛰고, 다음 반복을 진행하고자 할 때 continue를 사용한다.

- 1부터 9까지의 홀수의 합을 구할 때 다음과 같이 작성할 수 있다.

result = 0

for i in range(1, 10):
    if i % 2 == 0:
        continue
    result += i

print(result)

# 실행 결과
# 25

파이썬의 break 키워드

- 반복문을 즉시 탈출하고자 할 때 break를 사용한다.

- 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

함수와 람다 표현식

- 함수(Function)란 특정한 작업을 하나의 단위로 묶어 놓은 것을 의미한다.

- 함수를 사용하면 불필요한 소스코드의 반복을 줄일 수 있다.

함수 정의하기

- 함수를 사용하면 소스코드의 길이를 줄일 수 있다.

    - 매개변수 : 함수 내부에서 사용할 변수

    - 반환 값 : 함수에서 처리 된 결과를 반환

def 함수명(매개변수):
    실행할 소스코드
    return 반환 값

파라미터 지정하기

- 파라미터의 변수를 직접 지정할 수 있다.

    - 이 경우 매개변수의 순서가 달라도 상관이 없다.

def add(a, b):
    print('함수의 결과:', a + b)

add(b = 3, a = 7)

# 실행 결과
# 함수의 결과: 10

global 키워드

- global 키워드로 변수를 지정하면 해당 함수에서는 지역 변수를 만들지 않고, 함수 바깥에 선언된 변수를 바로 참조하게 된다.

a = 0

def func():
    global a
    a += 1
    
for i in range(10):
    func()
    
print(a)

# 실행 결과
# 10

- 만약 전역변수와 지역변수의 변수이름이 같다면, 지역변수가 우선적으로 참조된다.


여러 개의 반환 값

- 파이썬에서 함수는 여러 개의 반환 값을 가질 수 있다.

def operator(a, b):
    add_var = a + b
    subtract_var = a - b
    multiply_var = a * b
    divide_var = a / b
    return add_var, subtract_var, multiply_var, divide_var
    
a, b, c, d = operator(7, 3)
print(a, b, c, d)

람다 표현식

- 람다 표현식을 이용하면 함수를 간단하게 작성할 수 있다.

    - 특정한 기능을 수행하는 함수를 한 줄에 작성할 수 있다는 점이 특징이다.

def add(a, b):
    return a + b

# 일반적인 add() 메서드 사용
print(add(3, 7))

# 람다 표현식으로 구현한 add() 메서드
print((lambda a, b: a + b)(3, 7))

# 실행 결과
# 10
# 10

람다 표현식이 유용하게 사용될 수 있는 경우

- 어떠한 함수 자체를 입력으로 받는 또다른 함수가 존재할 경우

- 함수 기능이 간단하거나 단순히 한번 사용하고 말 경우

람다 표현식 예시: 내장 함수에서 자주 사용되는 람다 함수

array = [('홍길동', 50)('이순신', 32)('아무개', 74)]

def my_key(x):
    return x[1]
    
print(sorted(array, key=my_key))
print(sorted(array, key=lambda x: x[1]))

# 실행 결과
# [('이순신', 32), ('홍길동', 50), ('아무개', 74)]
# [('이순신', 32), ('홍길동', 50), ('아무개', 74)]

람다 표현식 예시: 여러 개의 리스트에 적용

list1 = [1, 2, 3, 4, 5]
list2 = [6, 7, 8, 9, 10]

result = map(lambda a, b: a + b, list1, list2)

print(list(result))

# 실행 결과
# [7, 9, 11, 13, 15]

실전에서 유용한 표준 라이브러리

- 내장함수 : 기본 입출력 함수부터 정렬 함수까지 기본적인 함수들을 제공한다.

    - 파이썬 프로그램을 작성할 때 없어서는 안 되는 필수적인 기능을 포함하고 있다.

- itertools : 파이썬에서 반복되는 형태의 데이터를 처리하기 위한 유용한 기능들을 제공한다.

    - 특히 순열과 조합 라이브러리는 코딩 테스트에서(완전탐색) 자주 사용된다.

- heapq : 힙(Heap) 자료구조를 제공한다.

    - 일반적으로 우선순위 큐 기능을 구현하기 위해 사용된다.

    - 대표적으로 다익스트라와 같은 최단경로에 사용

- bisect : 이진 탐색(Binary Search) 기능을 제공한다.

    - 기본적인 이진 탐색 기능을 사용할 때 효과적으로 사용 가능

- collections : 덱(deque), 카운터(Counter) 등의 유용한 자료구조를 포함한다.

- math : 필수적인 수학적 기능을 제공한다.

    - 팩토리얼, 제곱근, 최대공약수(GCD), 삼각함수 관련 함수부터 파이(pi)와 같은 상수를 포함한다.

 

자주 사용되는 내장 함수

# sum()
result = sum([1, 2, 3, 4, 5])
print(result)

# min(), max()
min_result = min(7, 3, 5, 2)
max_result = max(7, 3, 5, 2)
print(min_result, max_result)

# eval() 수식으로 표현된 식의 결과를 내줌
result = eval("(3+5)*7")
print(result)

# sorted()
result = sorted([9, 1, 8, 5, 4])
reverse_result = sorted([9, 1, 8, 5, 4], reverse=True)
print(result)
print(reverse_result)

# sorted() with key
array = [('홍길동', 35), ('이순신', 75), ('아무개', 50)]
result = sorted(array, key=lambda x: x[1], reverse=True)
print(result)

# 실행 결과
#15

#2 7

#56

#[1, 4, 5, 8, 9]
#[9, 8, 5, 4, 1]

#[('이순신', 75), ('아무개', 50), ('홍길동', 35)]

순열과 조합

- 모든 경우의 수를 고려해야 할 때 어떤 라이브러리를 효과적으로 사용할 수 있을까?

- 순열 : 서로 다른 n개에서 서로 다른 r개를 선택하여 일렬로 나열하는 것 (순서 다른것 구분)

    - {'A', 'B', 'C'}에서 세 개를 선택하여 나열하는 경우 : 'ABC', 'ACB', 'BAC', 'BCA', 'CAB', 'CBA'

from itertools import permutations

data = ['A', 'B', 'C'] # 데이터 준비

result = list(permutations(data, 3)) #모든 순열 구하기
print(result)

# 실행 결과
# [('A', 'B', 'C'), ('A', 'C', 'B'), ('B', 'A', 'C'), ('B', 'C', 'A'), ('C', 'A', 'B'), ('C', 'B', 'A')]

 

- 조합 : 서로 다른 n개에서 순서에 상관 없이 서로 다른 r개를 선택하는 것 (순서를 고려하지 않음)

    - {'A', 'B', 'C'}에서 순서를 고려하지 않고 두 개를 뽑는 경우 : 'AB', 'AC', 'BC'

from itertools import combinations

data = ['A', 'B', 'C'] # 데이터 준비

result = list(combinations(data,2)) # 2개를 뽑는 모든 조합 구하기
print(result)

# 실행 결과
# [('A', 'B'), ('A', 'C'), ('B', 'C')]

Counter

- 파이썬 collections 라이브러리의 Counter는 등장 횟수를 세는 기능을 제공한다

- 리스트와 같은 반복 가능한(iterable) 객체가 주어졌을 때 내부의 원소가 몇 번씩 등장했는지를 알려준다.

from collections import Counter

counter = Counter(['red', 'blue', 'red', 'green', 'blue', 'blue'])

print(counter['blue']) # 'blue'가 등장한 횟수 출력
print(counter['green']) # 'green'이 등장한 횟수 출력
print(dict(counter)) # 사전 자료형으로 반환

# 실행 결과
# 3
# 1
# {'red': 2, 'blue': 3, 'green': 1}

최대 공약수와 최소 공배수

- 최대 공약수를 구해야 할 때는 math 라이브러리의 gcd() 함수를 이용할 수 있다.

import math

# 최소 공배수(LCM)를 구하는 함수
def lcm(a, b):
    return a * b // math.gcd(a, b)

a = 21
b = 14

print(math.gcd(21, 14)) # 최대 공약수(GCD) 계산
print(lcm(21, 14)) # 최소 공배수(LCM) 계산

# 실행 결과
# 7
# 42
반응형

댓글

💲 추천 글