본문 바로가기

programming study/Algorithm

[동빈나]이코테 2021 강의 몰아보기 (2)(2020.12.30 ~ 31)

[동빈나]이코테 2021 강의 몰아보기 (2)(2020.12.30 ~ 31)

본 내용은 해당 강의 토대로 작성

파이썬 문법 부수기

자료형

  • 모든 프로그래밍은 데이터를 다루는 행위
  • Python의 자료형
    • 정수형, 실수형, 복소수형, 문자열, 리스트 , 튜플, 사전 등

1. 수 자료형

정수형(Integer)

  • 정수를 다루는 자료형
    • 양의 정수, 음의 정수, 0
  • 많은 유형의 문제에서 다루는 자료형
# 양의 정수
a = 1000 
print(a)

# 음의 정수
a = -7
print(a)

# 0
a = 0
print(a)

실수형(Real Number)

  • 소수점 아래의 데이터를 포함하는 수 자료형
    • 변수에 소수점울 붙인 수 대입하면 실수형 변수 처리
    • 소수부가 0, 정수부가 0인 소수는 0을 생략하고 작성 할 수 있음
# 양의 실수
a = 157.93
print(a)

# 음의 실수
a = -1837.2
print(a)

# 소수부가 0일 때 0을 생략
a = 5.
print(a)

# 정수부가 0일 때 0을 생략
a = .7
print(a)
  • 지수 표현 방식
    • e나 E를 이용한 지수 표현 방식을 이용할 수 있다.
    • e나 E 다음에 오는 수는 10의 지수부를 의미한다. ex) 1e9 = 109
    • 지수 표현 방식은 임의의 큰 수를 표현하기 위해 사용
    • 최단 경로 알고리즘에서는 도달할 수 없는 노드에 대해서 최단거리를 무한(NF)으로 설정
    • 이때 가능한 최댓값이 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)
  • 실수형 더 알아보기
    • IEEE754 표준에서, 실수형을 저장하기 위해 4바이트, 혹은 8바이트의 고정된 크기의 메모리를 할당하므로, 컴퓨터 시스템은 실수 정보를 표현하는 정확도에 한계를 가진다.
    • 예를 들어, 2진수에서 0.9를 정확하게 표현할 수 있는 방법 없음(미세한 오차 발생)
a = 0.3 + 0.6
print(a)        #0.89999999999999

if a == 0.9:
  print(Ture)
else:           #정확하게 표현할 수 없어서 False출력
  print(False)

이런경우 round()함수를 사용해서 반올림한다.

a = 0.3 + 0.6
print(round(a,4)) #0.9

if round(a, 4) == 0.9:
  print(Ture) #True 출력
else:
  print(False)

수 자료형의 연산

  • 수 자료형에서 사칙연산과 나머지 연산자가 사용된다.
  • 단 나누기 연산자(/)는 나눠진 결과를 실수형으로 반환
  • 모듈러 연산(%) 은 다양한 로직에서 사용
  • 몫 연산(//) 은 몫만을 출력
  • 거듭 제곱 연산자(**) 등 다양한 연산자 존재
a = 7
b = 3

# 나누기
print(a / b) # 2.3333333333333335

# 나머지
print(a % b) # 1

# 몫
print(a // b) # 2
a = 5
b = 3

# 거듭 제곱
print(a ** b) # 125

# 제곱근
print(a ** 0.5) # 2.2306797749979

2. 리스트 자료형

  • 여러 개의 데이터연속적으로 담아 처리
    • 배열 혹은 테이블이라고 부르기도 함
    • 반복적으로 뒤 쪽의 데이터를 이어 붙일 수 있음
    • 뒤 쪽에서 데이터를 제거하는 기능

리스트 초기화

  • 대괄호 []안에 원소를 넣어 초기화
  • 쉼표 ,로 원소 구분
  • 비어있는 리스트 선언
    • list() or []
  • 리스트 접근은 인덱스(Index) 값을 괄호에 넣는다.
    • 인덱스는 0부터
# 직접 데이터를 넣어 초기화
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]
print(a) # [1, 2, 3, 4, 5, 6, 7, 8, 9] 출력

# 네 번째 원소만 출력
pirnt(a[3]) # 4 출력

# 크기가 N이고, 모든 값이 0인 1차원 리스트 초기화
n = 10
a = [0] * n
print(a) # [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]

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

  • 인덱싱(Indexing) : 인덱스 값을 입력하여 리스트의 특정한 원소에 접근
    • Python의 인덱스 값은 양의 정수와 음의 정수 모두 사용 가능
    • 음의 정수를 넣으면 원소를 거꾸로 탐색
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 여덟 번째 원소만 출력
print(a[7])           # 8 출력

# 뒤에서 첫 번째 원소 출력
print(a[-1])          # 9 출력

# 뒤에서 세 번쨰 원소 출력
print(a[-3])         # 7 출력

# 네 번쨰 원소 값 변경
a[3] = 7
print(a)            #[1, 2, 3, 7, 5, 6, 7, 8, 9]
  • 리스트에서 연속적인 위치를 갖는 원소들을 가져와야 할 때는 슬라이싱(Slicing)을 이용
    • 대괄호 안에 콜론(:)을 넣어서 시작,끝 인덱스 설정
    • 끝 인덱스는 실제 인덱스보다 1을 더 크게 설정
a = [1, 2, 3, 4, 5, 6, 7, 8, 9]

# 네 번 째 원소만 출력
print(a[3])         # 4 출력

# 두 번째 원소부터 네 번째 원소까지
print(a[1:4])      # [2, 3, 4]

리스트 컴프리헨션

  • 리스트를 초기화하는 방법 중 하나
    • 대괄호 안에 조건문반복문을 적용하여 리스트 초기화
# 0부터 9까지의 수를 포함하는 리스트
array = [i for i in range(10)] # 0~9까지 i가 배열로 입력

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] # 홀수이므로 모듈러 연산 후 1이 남는 것만 입력

print(array) # [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]

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

print(array)# [1, 4 , 9, 16, 25, 36, 49, 64, 81]
  • 리스트 컴프리헨션은 2차원 리스트를 초기화할 때 효과적으로 사용
    • 특히, NxM크기의 2차원 리스트에서 유용
# N x M 크기의 2차원 리스트 초기화
n = 4
m = 3
array = [[0] * m for _ in range(n)]
print(array) #[[0,0,0],[0,0,0],[0,0,0]]
  • 언더바의 사용
    • 반복을 수행하지만 변수의 값을 무시할 때 사용

리스트 관련 기타 메서드

변수명.append() : 리스트 뒤에 원소를 하나 삽입. 시간 복잡도 O(1)

변수명.sort() : 기본 정렬 기능으로 오름차순 정렬. true 입력 시, 내림차순 정렬. 시간 복잡도 O(NlogN)

변수명.reverse() : 리스트의 원소 순서를 모두 뒤집는다. 시간 복잡도 O(N)

insert(삽입할 위치 인덱스, 삽입할 값) : 특정한 인덱스 위치에 원소를 삽입할 때 사용. 시간 복잡도 O(N)

변수명.count(특정값) : 리스트에서 특정한 값을 가지는 데이터이 개수를 셀 때 사용. 시간 복잡도 O(N)

변수명.remove(특정값) : 특정한 값을 갖는 원소를 제거하는데, 값을 가진 원소가 여러개면 하나만 제거. 시간 복잡도 O(N)

a = [1, 4, 3]
print("기본 리스트: ", a) # [1, 4, 3]

# 리스트에 원소 삽입
a.append(2)
priint("삽입 : ", a) # [1, 4, 3, 2]

# 오름차순 정렬
a.sort()
print("오름차순 정렬:", a) # [1, 2, 3, 4]

# 내림차순 정렬
a.sort(1)
print("내림차순 정렬:" a) # [4, 3, 2, 1]

# 리스트 원소 뒤집기
a.reverse()
print("원소 뒤집기 : ", a) # [1, 2, 3 ,4]

# 특정 인덱스에 데이터 추가
a.insert(2, 3)
print("인덱스 2에 3추가 : ", a) #[1, 2, 3, 3, 4]

# 특정 값인 데이터 개수 세기
print("값이 3인 데이터 개수 : ", a.count(3)) # 2

# 특정 값 데이터 삭제
a.remove(1)
print("값이 1인 데이터 삭제 : " , a) # [2, 3, 3, 4]

# 특정 값을 가지는 원소를 모두 제거하기
a = [1, 2, 3, 4, 5, 5, 5]
remove_set = {3,5} # 집합 자료형

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

3. 문자열 자료형

  • 문자열 변수를 초기화할 때는 큰따옴표("")나 작은 따옴표('')를 이용한다.
  • 문자열 안에 큰 따옴표나 작은 따옴표가 포함되어야 하는 경우가 있다.
    • 전체 문자열 큰따옴표 -> 내부 작은 따옴표
    • 전체 문자열 작은따옴표 -> 내부 큰 따옴표
    • 백슬래시( \ ) 사용시, 큰따옴표나 작은따옴표를 원하는 만큼 포함
data = 'Hello world'
print(data) # Hello World

data = "Don't you know \"Python\"?"
print(data) # Don't you know "Python"?

문자열 연산

  • 문자열 변수에 덧셈(+)을 이용하면 문자열이 더해져서 연결(Concatenate)된다.
  • 문자열 변수를 특정한 양의 정수와 곱하면, 문자열이 그 값만큼 여러 번 더해진다.
  • 문자열에서도 슬라이싱을 이용할 수 있다.
    • 인덱스의 값을 변경할 수 는 없다.(Immutable)
a = "Hello"
b = "World"
print(a + " " + b) # Hello World

a = "String"
print(a*3) # StringStringString

a = "ABCDE"
pritn(a[2 : 4]) # CD

4. 튜플 자료형

  • 리스트와 유사하지만 아래의 문법적 차이가 있다.
    • 한 번 선언된 값을 변경할 수 없다.
    • 소괄호( )를 이용
  • 튜플은 리스트에 비해 상대적으로 공간 효율적
a = (1, 2, 3, 4, 5, 6, 7, 8, 9,)

# 네 번째 원소만 출력
print(a[3]) # 4

# 두 번째 원소부터 네 번째 원소까지
print(a[1 : 4]) # (2, 3, 4) 
  • 서로 다른 성질의 데이터를 묶어서 관리할 때
    • 최단 경로 알고리즘에서는 (비용, 노드 번호)의 형태로 튜플 자료형을 자주 사용
  • 데이터의 나열을 해싱(Hashing)의 키 값으로 사용
    • 변경이 불가능하기 때문
  • 리스트보다 메모리르 효율적으로 사용할 때

5. 사전 자료형

  • 키(Key)값(Value)의 쌍을 데이터로 가지는 자료형
  • 키(Key)는 변경 불가능(Immutable)한 자료형
  • Python의 사전 자료형은 해시 테이블(Hash Table)을 이용, O(1)의 시간에 처리 가능
data = dict()
data['사과'] = 'Apple'
data['바나나'] = 'Banana'
data['코코넛'] = 'Coconut'

# 다른 초기화 방법
data = {
  '사과' : 'Apple',
  '바나나' : 'Banana',
  '코코넛' : 'Coconut'
}


print(data) # {'사과' : 'Apple', '바나나' : 'Banana', '코코넛' : 'Coconut'}

ir '사과' in data
    print("'사과'를 키로 가지는 데이터가 존재합니다.") # 출력
  • 사전 자료형에서는 키와 값을 별도로 뽑아내기 위한 메서드를 지원
    • 키 데이터만 뽑아서 리스트로 이용 : keys()함수 이용
    • 값 데이터만 뽑아서 리스트로 이용 : values()함수 이용
data = dict()
data['사과'] = 'Apple'
data['바나나'] = 'Banana'
data['코코넛'] = 'Coconut'

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

# 값 데이터만 담은 리스트
value_list = data.values()
print(key_list)     # dict_keys(['사과', '바나나', '코코넛'])
print(value_list)   # dict_values(['Apple', 'Banana', 'Coconut']) #list함수로 리스트화 할 수 있다.

# 각 키에 따른 값 하나씩 출력
for key in key_list: #Apple Banana Coconut
  print(data[key])

6. 집합 자료형

  • 중복을 허용하지 않는다.
  • 순서가 없다.
  • 리스트 혹은 문자열을 이용해서 초기화 가능
    • set()함수 이용
  • 중괄호({})안에 각 원소를 콤마(,) 기준으로 구분하여 삽입
  • O(1)시간에 처리 가능
# 집합 자료형 초기화 방법 1
data = set([1, 1, 2, 3, 4, 4, 5])
print(data) # {1, 2, 3, 4, 5}

# 집합 자료형 초기화 방법 2
data = {1, 1, 2, 3, 4, 4, 5}
print(data) # {1, 2, 3, 4, 5}
  • 합집합, 교집합, 차집합 연산
    • 합집합 : 집합 A에 속하거나 B에 속하는 원소로 이루어진 집합
    • 교집합 : 집합 A에도 속하고 B에도 속하는 원소로 이루어진 집합
    • 차집합 : 집합 A의 원소 중에서 B에 속하지 않는 원소들로 이루어진 집합
a = set([1, 2, 3, 4, 5])
b = set([3, 4, 5, 6, 7])

# 합집합
print(a | b) # {1, 2, 3, 4, 5, 6, 7}

# 교집합
print(a & b) # {3, 4, 5}

# 차집합
print(a - b) # {1, 2}
  • 집합 자료형 관련 함수
data = set([1, 2, 3])
print(data) # {1, 2, 3}

# 새로운 원소 추가
data.add(4)
print(data) # {1, 2, 3, 4}

# 새로운 원소 여러 개 추가
data.update([5, 6])
print(data) # {1, 2, 3, 4, 5, 6}

# 특정한 값을 갖는 원소 삭제
data.remove(3)
print(data) # {1, 2, 4, 5, 6}

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

  • 순서가 없으므로 인덱싱으로 값을 얻을 수 없다.
    • 사전의 키(key) 혹은 집합의 원소(Element)를 이용해 O(1)의 시간 복잡도로 조회
    • 키나 원소의 값으로는 변경 불가능한 문자열이나 튜플이 와야한다.