이것이 취업을 위한 코딩테스트다 with 파이썬
문자열 자료형
문자열 초기화
- 문자열 변수를 초기화할 때는 큰따옴표 / 작은따옴표를 이용한다.
- 문자열을 큰따옴표로 구성하는 경우, 내부적으로 작은따옴표를 포함할 수 있다.
- 반대로 문자열을 작은따옴표로 구성하는 경우, 내부적으로 큰따옴표를 포함할 수 있다.
- 혹은 백슬래시(\)를 사용하면 큰따옴표나 작은따옴표를 문자열에 원하는 만큼 포함시킬 수 있다.
data = "Don't you know \"Python\"?"
# 출력: Don't your know "Python"?
문자열 연산
파이썬은 문자열에 대한 연산도 지원하는데, 단순히 문자열을 처리할 때 유용하게 사용할 수 있다.
a = "Hello"
b = "World"
print(a + " "+ b) # Hello World
x = "String"
print(x * 3) # StringStringString
파이썬의 문자열은 내부적으로 리스트와 같이 처리되며, 문자열은 여러 개의 문자가 합쳐진 리스트라고 볼 수 있다.
따라서 문자열 데이터에 대해서도 인덱싱과 슬라이싱을 이용할 수 있다.
a = "ABCDEF"
print(a[2 : 4]) # CD
튜플 자료형
튜플 자료형은 리스트와 거의 비슷하지만 약간의 차이가 있다.
- 튜플은 한 번 선언된 값을 변경할 수 없다.
- 리스트는 대괄호 [] 를 이용하지만, 튜플은 소괄호 () 를 이용한다.
a = (1, 2, 3, 4)
print(a) # 출력: (1, 2, 3, 4)
a[2] = 7 # TypeError: 'tuple' object does not support item assignment (대입연산자(=) 사용 불가)
튜플 자료형은 그래프 알고리즘을 구현할 때 자주 사용된다.
다익스트라 최단 경로 알고리즘처럼 최단 경로를 찾아주는 알고리즘의 내부에서는 우선순위 큐를 이용하는데,
해당 알고리즘에서 우선순위 큐에 한 번 들어간 값은 변경되지 않는다.
그래서 우선순위 큐에 들어가는 데이터를 튜플로 구성하여 소스코드를 작성한다.
이렇게 알고리즘을 구현하는 과정에서 일부러 튜플을 이용하게 되면 변경하면 안 되는 값이 변경되고 있지는 않은지 체크할 수 있다.
또한 튜플은 리스트에 비해 상대적으로 공간 효율적이고, 일반적으로 각 원소의 성질이 서로 다를 때 주로 사용한다.
흔히 다익스트라 최단 경로 알고리즘에서는 '비용'과 '노드 번호'라는 서로 다른 성질의 데이터를 (비용, 노드 번호)의 형태로 함께 튜플로 묶어서 관리하는 것이 관례이다.
사전 자료형
사전 자료형은 키(Key)와 값(Value)의 쌍을 데이터로 가지는 자료형이다.
리스트나 튜플은 값을 순차적으로 저장한다는 특징이 있다. 예를 들어 리스트의 값이 [1, 2, 3]이라고 한다면, 첫 번째 원소는 a[0]으로 1이라는 값을 가진다.
하지만 사전 자료형은 키-값 쌍을 데이터로 가진다는 점에서, 우리가 원하는 변경 불가능한 데이터를 키로 사용할 수 있다.
키(Key) | 값(Value) |
사과 | Apple |
바나나 | Banana |
코코넛 | Coconut |
키를 한글 단어로 넣고, 값으로 영어 단어를 넣어 '사과'의 영어 단어를 알고 싶다면
'사과'라는 키 값을 가지는 데이터에 바로 접근하면 된다.
파이썬의 사전 자료형은 내부적으로 '해시 테이블'을 이용하므로,
기본적으로 데이터의 검색 및 수정에 있어서 O(1)의 시간에 처리할 수 있다.
키-값 쌍으로 구성된 데이터를 처리함에 있어서 리스트보다 훨씬 빠르게 동작한다.
data = dict()
data['사과'] = 'Apple'
data['바나나'] = 'Banana'
data['코코넛'] = 'Coconut'
print(data) # {'사과': 'Apple', '바나나': 'Banana', '코코넛': 'Coconut'}
if '사과' in data:
print("'사과'를 키로 가지는 데이터가 존재합니다.") # 출력
사전 자료형은 코테에서도 자주 사용될 수 있다.
학생 번호가 1부터 10,000,000까지 있는 상황에서 최대 10,000명의 학생을 선택했다고 가정해보자.
특정 학생 번호가 주어졌을 때 해당 학생이 선택되었는지를 알고 싶을 때
리스트를 이용한다면 각 번호가 '선택되었는지를 저장할 수 있는' 리스트를 만들어야 하고, 1,000만 개 데이터를 저장할 수 있는 리스트 중 999만 개 가량의 데이터는 쓰이지 않으므로 많은 메모리 공간이 낭비된다.
하지만 사전 자료형을 이용하는 경우 10,000개의 데이터만 사전 자료구조에 들어가므로 훨씬 적은 메모리 공간을 사용할 수 있다.
사전자료형에 특정한 원소가 있는지 검사할 때는 원소 in 사전
의 형태를 사용할 수 있다.
이는 리스트나 튜플에 대해서도 사용할 수 있는 문법이다.
** 리스트, 문자열, 튜플 등 원소들을 차례로 반복할 수 있는 자료형을 Iterable 자료형이라고 한다.
Iterable 자료형들은 그 내부에 원소들을 포함하는 컨테이너 역할도 하는 거이 대부분이기에 in 문법도 사용이 가능하다.
사전 자료형 관련 함수
사전 자료형을 잘 이해하기 위해서는 관련한 다양한 함수에 대해서 알아야 한다.
대표적으로는 키와 값을 별도로 뽑아내기 위한 함수가 있다.
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'])
# 각 키에 따른 값을 하나씩 출력
for key in key_list:
print(data[key])
집합 자료형
집합은 기본적으로 리스트 혹은 문자열을 이용해서 만들 수 있는데, 집합은 다음과 같은 특징이 있다.
- 중복을 허용하지 않는다
- 순서가 없다
리스트나 튜플은 순서가 있기 때문에 인덱싱을 통해 자료형의 값을 얻을 수 있었다면,
사전 자료형과 집합 자료형은 순서가 없기 때문에 인덱싱으로 값을 얻을 수 없다.
집합 자료형에서는 키가 존재하지 않고, 값 데이터만을 담게 된다.
특정 원소가 존재하는지를 검사하는 연산의 시간 복잡도는 사전 자료형과 마찬가지로 O(1) 이다.
언급했던 '학생 번호가 주어졌을 때 해당 학생이 선택되었는지 여부를 출력하는 문제' 에 대해서도 집합 자료형이 효과적으로 사용될 수 있다.
특히 '특정한 데이터가 이미 등장한 적이 있는지 여부'를 체크할 때 매우 효과적이다.
집합 자료형을 초기화할 때는 set() 함수를 이용하거나, 중괄호({}) 안에 각 원소를 콤마(,)를 기준으로 구분해서 넣으면 된다.
# 집합 자료형 초기화 방법 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 = set([1, 2, 3, 4, 5])
b = set([3, 4, 5, 6, 7])
print(a | b) # 합집합
print(a & b) # 교집합
print(a - b) # 차집합
집합 자료형 관련 함수
집합 자료형 또한 다른 자료형과 마찬가지로 다양한 함수가 존재한다.
add()
:하나의 집합 데이터에 값을 추가 - 시간복잡도 O(1)update()
: 여러 개의 값을 한꺼번에 추가remove()
: 특정한 값 제거 - 시간복잡도 O(1)
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}