#3. list
■ 리스트 컴프리핸션
- 리스트를 초기화하는 방법 중 하나: 대괄호 안에 조건문과 반복문을 적용하여 리스트를 초기화
array = [i for i in range(10)] # 반복, 조건문 먼저 작성을 추천
- 2차원 리스트를 초기화할 때 효과적으로 사용
#좋은 예
array = [[0]*m for _ in range(n)] # n번 반복마다 길이가 m인 리스트 초기화
#나쁜 예
array = [[0]*m]*n
# 1) 파이썬 list 자료형을 활용하여 변수값 할당 시
# 2) 내부적으로 list는 객체 형태로 인식되어 각각의 주소값 가짐
# 3) 단순 곱셈 시 참조값을 복사하는 것과 같기에
# 4) 내부적으로 포함된 모든 list가 동일한 객체로 인식됨.
# 5) 즉, 하나 바꾸면 전부 다 바뀔 수 있음
■ 리스트 관련 기타 메서드
- append() /변수명.append()/리스트에 원소를 하나 삽입 시 사용 / O(1)
- sort() /변수명.sort()(reverse=True)/오름차순, 내림차순 정렬/O(NlogN)
- reverse() /변수명.reverse()/리스트의 원소 순서 모두 뒤집음/O(N)
- insert() /insert(위치idx,값)/특정 idx에 원소 삽입 시 사용 /O(N)
- count() /변수명.count(특정 값)/특정 값 갖는 데이터 개수 파악/O(N)
- remove() /변수명.remove(특정 값)/특정 값 갖는 원소 제거(하나만)/O(N)
- 특정 원소 모두 제거 예시: 집합 자료형 사용
#4 문자열, 튜플, 집합 자료형
■ 문자열 (string)
- 인덱싱과 슬라이싱을 이용 가능 but. 문자열은 특정 인덱스의 값을 변경할 수는 없음
■ 튜플 (tuple)
- 한번 선언된 값 변경 불가능(원소 할당 연산 불가능)
- 리스트의 대괄호([])가 아닌 소괄호(()) 사용
- 리스트에 비해 상대적으로 공간 효율적(더 적은 메모리 사용)
- 좋은 사용 예
- 서로 다른 성질 데이터 묶어서 관리할 때
- 최단 경로 알고리즘 (비용, 노드 번호)
- 데이터의 나열을 해싱 키 값으로 사용해야할 때
- 변경이 불가능하므로 리스트와 달리 키 값으로 사용 가능
- 리스트보다 메모리를 효율적으로 사용해야 할 때
- 서로 다른 성질 데이터 묶어서 관리할 때
■ 사전(dictionary)
- 키, 값 한 쌍의 데이터 가짐
- 리스트, 튜플 같이 값을 순차적으로 저장하는 것과 대비됨
- 변경 불가능한(Immutable) 자료형을 키로 사용 가능
- 해시 테이블을 이용하므로 데이터의 조회 및 수정에 O(1)의 시간에 처리
#전부 동일한 동작
data = dict()
data[key] = value
data.keys()
data.values()
b = {key:value}
■ 집합 자료형
- 중복 허용X, 순서X
- 리스트 혹은 문자열 이용해서 초기화 (set() 함수 사용)
- 중괄호 안에 각 원소를 콤마(,)를 기준으로 구분 삽입하여 초기화 가능
- 데이터 조회, 수정에 O(1) 처리 가능
- 합집합, 교집합, 차집합 사용 가능
- add, update(여러개 원소 추가), remove
#5 기본 입출력
■ 입력
- input() 함수는 한 줄의 문자열 입력
- map() 함수는 리스트의 모든 원소에 각각 특정한 함수를 적용할 때 사용
#공백 기준으로 구분된 데이터 입력
list(map(int, input().split()))
#공백 기준 구분된 데이터 수 적을 경우
변수1, 변수2 = map(int, input().split())
#공백 구분하여 원소가 문자열인 리스트 생성
data=input().split()
- 입력 최대한 빠르게 받아야 하는 경우
- sys.stdin.redline() 메서드 이용 (sys라이브러리 정의)
- 입력의 개수가 많을 때 예방 (이진탐색, 정렬, 그래프 관련)
# 단, 입력 후 엔터가 줄 바꿈 기호로 입력됨
# rstrip() 메서드와 함께 사용(개행문자 없엠, 문자열 사용시)
import sys
data = sys.stdin.readline().rstrip()
print(data)
■ 출력
- 기본적으로 출력 이후에 줄 바꿈을 수행 (원치 않는 경우, end 속성을 이용)
print(변수, end=" ")
- 같은 자료형끼리 연산하여 출력 가능
- f-stiring : 중괄호 안에 변수명 기입하여 간단히 문자열과 정수 함께 사용
print(f"정답은 {answer}입니다.")
#6 조건문
■ 논리 연산자
- &&, ||, ! 가 아닌 and, or, not과 같은 직관적인 논리 연산자 제공
■ 기타 연산자
- x in 리스트, 문자열, 튜플, 딕셔너리 : x가 들어 있을 때 True
- x not in (다수 데이터 자료형) : x가 들어있지 않을 때 True
■ pass
- 일단 넘어가는 코드 (pass 대신 실행할 블록에 명시 안하면 오류 처리)
■ 조건부 표현식
- result = "Sucess" if score >= 80 else "Fail" 참일 경우 왼쪽, 아닐 경우 오른쪽 값 대입
■ 부등식
- 수학의 부등식 그대로 사용 가능, 예) 0 < x < 10
- 타 언어의 경우 부등식 순차적으로 실행
x=25
# [0 < X < 20]
# [true < 20] ※true=1 → 즉, 항상 True
#7 함수
■ 용어
- 인자(argument): 함수를 호출할 떄 넣는 값
- 매개 변수(parameter): 함수 내부적으로 전달받고자 하는 값들을 명시해 놓은 것
■ global 키워드 (전역 변수를 사용하고 싶을 때)
- C, C++ 에서는 global이 없으면 자동적으로 전역 변수 참조
- 전역 변수의 대입이 아니라 단숨 참조의 경우 오류 없음
- 전역 변수로 list가 선언되어 있을 때 list 객체의 내부 method를 호출하는 것은 오류 없이 수행 (예: append, pop, ... )
- 함수 안에 동일한 이름의 지역변수 있을 시 내부적으로 선언된거 우선
- 혹은 같은 포지션의 변수 선언이 우선
■ 여러 개의 반환 값
- 패킹: return 변수1, 변수2
- 언패킹: 변수1, 변수2 = 함수(인자)
■ 람다 표현식
- 어떠한 함수 자체를 입력으로 받는 또 다른 함수 존재할 시 유용
- 내장함수에 자주 사용 (예: sorted)
# 람다 함수로 두 수에 대한 add 함수 구현
print((lambda a, b: a + b)(3,7))
# 어떠한 함수 자체를 입력으로 받는 또 다른 함수가 존재할 시 유용
array = [('홍길동', 50), ('이순신', 32), ('아그몬', 74)]
print(sorted(array, reverse=True, key=lambda x: x[1]))
# 정렬 기준을 키 속성의 값으로 넣어줌
d = dict()
d['a'] = 66
d['i'] = 20
d['e'] = 30
d['d'] = 33
d['f'] = 50
d['g'] = 60
d['c'] = 22
d['h'] = 80
d['b'] = 11
print(sorted(d.items(), key=lambda x: x[1]))
# 리스트 요소 합 구하기
# 검색용 태그: 요소별 합, 요소별 계산, 요소 계산, 리스트 계산, 요소끼리 계산]
list1 = [1,2,3,4,5]
list2 = [6,7,8,9,10]
result = map(lambda a, b: a * b, list1, list2)
print(list(result))
#8 실전 표준 라이브러리
■실전에서 유용한 표준 라이브러리
- 내장 함수
- itertools
- 반복 형태의 데이터 처리 유용
- 특히 순열과 조합 라이브러리 포함: 완전탐색에서 소스코드 간결화
- heapq
- 힙 자료구조 제공
- 일반적으로 우선순위 큐 기능 구현: 다익스트라(최단경로)
- bisect
- 기본적인 이진 탐색
- collections
- 덱(deque), 카운터(Counter) 등의 유용한 자료구조
- math
- 팩토리얼, 제곱근, 최대공약수(GCD), 삼각함수 관련 함수
- 파이(pi)와 같은 상수 포함
■ 표준 라이브러리 예시
- 내장 함수
- eval(): 수식으로 표현된 식을 계산한 결과를 수로 반환 예)result = eval("(3+5)*7")
- 순열과 조합: 서로 다른 n개에서
- 순열: 서로 다른 r개를 선택하여 일렬로 나열하는 것
- 조합: 순서에 상관없이 서로 다른 r개를 선택하는 것
# 순열
from itertools import permutations
data = ['A', 'B', 'C']
result = list(permutations(data, 3) #모든 순열 구하기
#조합
from itertools import combinations
data = ['A', 'B', 'C']
result = list(combinations(data, 2))
#중복
중복순열: product / 중복조합: combinations_with_replacement
- counter: word 클라우드(?) 만들 때 사용
- math
- 최대 공약수: math.gcd(a,b)
- 최소 공배수: math.lcm(a,b) 또는 a*b//math.gcd(a,b)