Programming/Python

[Python] 파이썬 자료형(리스트/튜플/사전/집합) 정리

킹우현 2023. 2. 22. 19:57

이번 포스팅에서는 리스트와 튜플만으로는 시간복잡도를 해결할 수 없는 문제를 많이 접하다보니 Python에서 제공하는 여러 자료형과 관련 함수들을 활용하기 위해 정리하고자 한다.

 

1) 리스트(List) 자료형 (배열/테이블) 📝

List는 여러 개의 데이터를 연속적으로 담아 처리하기 위해 사용

파이썬의 리스트 자료형은 C나 자바와 같은 프로그래밍 언어의 ‘배열’ 기능을 포함하고 있으며, 내부적으로 연결 리스트 자료구조를 채택하고 있어서 append(), remove() 등의 메소드를 지원한다.

 

1-1) 리스트 만들기

리스트는 대괄호[] 안에 원소를 넣어서 초기화하며, 쉼표로 원소를 구분한다.

 

비어있는 리스트를 선언하고자 할 때는 list() 또는 [] 를 이용할 수 있다.

 

 

코딩 테스트 문제에서는 주로 크기가 N인 1차원 리스트를 초기화 해야 하는데, 위와 같은 방식으로 초기화하면 편하다.

 

1-2) 리스트 슬라이싱

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

 

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

 

1-3) 리스트 컴프리헨션

array = []
for i in range(20):
    if i%2 == 1:
        array.append(i)

array2 = [i for i in range(20) if i%2 == 1]

print(array)
print(array2)

#[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
#[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
array3=[i*i for i in range(1,10)]

print(array3)

# [1, 4, 9, 16, 25, 36, 49, 64, 81]

리스트 컴프리헨션은 리스트를 초기화하는 방법 중 하나이다. 

 

리스트 컴프리헨션을 이용하면 대괄호 안에 조건문과 반복문을 넣는 방식으로 리스트를 초기화 할 수 있다. ⭐️⭐️

 

 

n = 3
m = 4

array = [[0]*m for _ in range(n)]
print(array)

# [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]]

이러한 리스트 컴프리헨션은 코딩 테스트에서 2차원 리스트를 초기화할 때 매우 효과적으로 사용된다 !

 

1-4) 리스트 관련 메소드

  • len() : 리스트에 있는 데이터 개수 반환
  • max() : 리스트에 있는 데이터 데이터 중 가장 큰 데이터 반환
  • min() : 리스트에 있는 데이터 데이터 중 가장 작은 데이터 반환
  • sum() : 리스트에 있는 데이터 데이터의 합을 반환
  • sorted() : 리스트 정렬 후 반환
    ✔️ Default 값이 오름차순, 내림차순으로 하려면 옵션 추가(reverse=True)
  • revered() : 리스트를 거꾸로 반환
  • index() : 존재하면 index번호를 반환하고, 없으면 오류
  • count() : 해당 데이터 갯수 반환
  • append() : 리스트의 맨 끝에 데이터를 추가함
  • pop() : 리스트의 해당 인덱스에 위치한 데이터를 제거하고 반환
  • insert() : 해당 위치에 데이터 삽입
  • remove() / del  : 해당 데이터 삭제
  • sort() : 리스트의 데이터를 정렬(원본 리스트 자체를 수정)

리스트와 관련한 기타 메소드를 사용하면 리스트 자료형을 효과적으로 이용할 수 있다.

이중에서 insert() 함수와 append(), remove()를 유심히 보자.

 

코딩 테스트에서 insert() 함수를 사용할 때 시간 복잡도가 O(N)이다.

 

파이썬의 리스트 자료형의 append() 함수는 O(1)에 수행되는데 반해 insert() 함수는 동작이 느리다. (중간에 원소를 삽입한 뒤에 리스트의 원소 위치를 조정해줘야 하기 때문)

따라서 insert() 함수를 남발하면 시간초과로 통과하지 못할 수 있다 !

 

1-5) 리스트에서 특정 원소를 제거하는 법

remove() 함수 또한 리스트에서 중간 원소를 삭제한 뒤에 다시 원소 위치를 조정해주어야 하기 때문에 O(N)이 소요된다. 그렇다면 특정한 값의 원소를 모두 제거하려면 어떻게 해야 할까 ?

👉🏻 집합(set)을 사용한다 !

 

2) 튜플(Tuple) 자료형 📃

파이썬의 튜플 자료형은 리스트와 비슷하지만, 다음과 같은 차이가 있다.

  1. 튜플은 한 번 선언된 값을 변경할 수 없다.
  2. 리스트는 대괄호[]를 사용하지만, 튜플은 소괄호()를 사용한다.

튜플 자료형은 그래프 알고리즘을 구현할 때 자주 사용된다.

 

예를 들어 다익스트라 최단 경로 알고리즘처럼 최단 경로를 찾아주는 알고리즘 내부에서는 우선순위 큐를 이용하는데 해당 알고리즘에서 우선순위 큐에 한 번 들어간 값은 변경되지 않는다.

 

따라서 그 우선순위 큐에 들어가는 데이터를 튜플로 구성하여 소스코드를 작성한다.

 

이렇게 알고리즘을 구현하는 과정에서 튜플을 이용하게 되면 변경하면 안되는 값이 변경되고 있지는 않은지 체크할 수 있다.

 

또한 튜플은 리스트에 대해 상대적으로 공간 효율적이고, 일반적으로 각 원소의 성질이 서로 다를 때 주로 사용한다. ⭐️⭐️

흔히 다익스트라 최단 경로 알고리즘에서는 ‘비용(Cost)’와 ‘노드 번호(Node number)’라는 서로 다른 성질의 데이터를 (비용, 노드 번호) 형태로 함께 튜플로 묶어서 관리한다.

 

2-1) 튜플 관련 메소드

  • len() : 튜플에 있는 데이터 개수 반환
  • max() : 튜플에 있는 데이터 데이터 중 가장 큰 데이터 반환
  • min() : 튜플에 있는 데이터 데이터 중 가장 작은 데이터 반환
  • sum() : 튜플에 있는 데이터 데이터의 합을 반환
  • sorted() : 튜플 정렬 후 리스트로 반환(🔥 튜플로 반환받고 싶으면 형변환)
    ✔️ Default 값이 오름차순, 내림차순으로 하려면 옵션 추가(reverse=True)
  • revered() : 튜플의 데이터를 거꾸로 바꾼 뒤, 리스트반환(🔥 튜플로 반환받고 싶으면 형변환)
  • index() : 해당 데이터 위치 찾기(없으면 오류)
  • count() : 해당 데이터 갯수 반환(없으면 0반환)
  • tuple은 sort() 메소드 사용 불가, sorted() 함수만 가능 (sort 메소드는 원본 자체의 순서를 바꾸기 때문)

3) 사전(Dictionary) 자료형 📖

data = dict()

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

print(data)

#{'사과': 'Apple', '바나나': 'Banana', '코코넛': 'Coconut'}

사전 자료형은 Key와 Value의 쌍을 데이터로 가지는 자료형이다. 리스트나 튜플은 값을 순차적으로 저장한다는 특징이 있다.

하지만 사전 자료형은 키-값 쌍을 데이터로 가진다는 점에서, 우리가 원하는 변경 불가능한 데이터를 키로 사용할 수 있다. (순서가 X)

 

파이썬의 사전 자료형은 내부적으로 ‘해시 테이블(Hash Table)’을 이용 하므로 기본적으로 데이터의 검색 및 수정에 있어서 O(1)의 시간에 처리할 수 있다.⭐️⭐️⭐️⭐️

Key-Value 쌍으로 구성된 데이터를 처리함에 있어서 리스트보다 시간 복잡도가 낮고, 훨씬 빠르게 동작한다 !

 

사전 자료형을 사용하였을 때 리스트를 사용하였을 때 보다 공간 효율적인 경우가 있다. (훨씬 적은 메모리 공간 사용)

 

data = dict()

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

if '사과' in data:
    print("사과를 키로 가지는 데이터가 존재")

튜플이나 리스트, 사전 자료형에 특정한 원소가 있는지 검사할 때는 ‘원소 in 사전’ 형태를 사용할 수 있다. 

 

3-1) 사전 자료형 관련 메소드

data = dict()

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

print(data.keys()) # dict_keys(['사과', '바나나', '코코넛'])
print(data.values()) # dict_values(['Apple', 'Banana', 'Coconut'])

for key in data.keys():
    print(key) # 사과 바나나 코코넛

for key in data.keys():
    print(data[key]) # Apple Banana Coconut

for value in data.values():
    print(value) # Apple Banana Coconut
  • clear( ) : 딕셔너리의 모든 elements를 삭제
  • copy( ) : 딕셔너리의 얕은 복사를 반환 (구체적인 설명 : 딕셔너리 타입 복사시 주의!! ( copy, deepcopy ))
  • fromkeys(keys, value) : 특정 key와 value의 딕셔너리를 반환
  • get(keyname, value) : 특정 key의 value를 반환
  • items( ) : 각 key와 value의 튜플이 담긴 리스트 반환
  • keys( ) : 딕셔너리의 모든 key의 리스트 반환
  • values( ) : 딕셔너리의 모든 value들을 담은 리스트 반환
  • pop(keyname, defaultvalue) : 특정 요소를 반환하고 삭제
  • popitem( ) : 마지막으로 삽입된 key-value를 삭제
  • setdefault( ) : 특정 key의 value를 반환. 만약 해당하는 key가 없다면, key를 삽입
  • update(iterable) : 특정 key-value 조합을 삽입

사전 자료형의 대표적인 함수로는 Key와 Value를 뽑아내기 위한 함수가 있다.

키 데이터만 뽑아서 리스트를 이용할 때는 keys()함수를 사용하고, 값 데이터만을 뽑아서 리스트로 이용할 때는 values()함수를 사용한다 !

 

4) 집합(Set) 자료형

data = set([1,1,2,3,4,4,5])
print(data) # {1, 2, 3, 4, 5}

data = {1,1,2,3,4,4,5,6}
print(data) # {1, 2, 3, 4, 5, 6}

집합은 기본적으로 리스트 혹은 문자열을 이용하여 만들 수 있는데, 다음과 같은 특징이 있다.

  • 중복을 허용하지 않는다.
  • 순서가 없다.

이전에 다루었던 리스트나 튜플은 순서가 있기 때문에 인덱싱을 통해 자료형의 값을 얻을 수 있었지만, 사전 자료형과 집합 자료형은 순서가 없기 때문에 인덱싱으로 값을 얻을 수 없다.

 

이와 더불어 집합 자료형에서는 Key가 존재하지 않고 값 데이터만을 담게 된다.

 

특정 원소가 존재하는지를 검사하는 연산의 시간 복잡도는 사전 자료형과 마찬가지로 O(1)이다.⭐️⭐️⭐️⭐️

 

집합 자료형은 특히 ‘특정한 데이터가 이미 등장한 적이 있는지 여부’를 체크할 때 매우 효과적이다.

집합 자료형을 초기화할 때는 set() 함수를 이용하거나, 중괄호{} 안에 각 원소를 쉼표를 기준으로 구분해서 넣으면 된다.

 

4-1) 집합 자료형의 연산

a = {1,2,3,4,5}
b= {3,4,5,6,7}

print(a|b) # 합집합
print(a&b) # 교집합
print(a-b) # 차집합

기본적인 집합 연산으로는 합집합, 교집합, 차집합 연산이 있다. 파이썬은 이러한 집합 자료형의 연산에 대해서 다루고 있다.

 

4-2) 집합 자료형 관련 메소드

a = {1,2,3,4,5}
b= {3,4,5,6,7}

a.add(6)
print(a)

b.update({8,9})
print(b)

a.remove(6)
print(a)
  • len() : 집합에 있는 데이터 개수 반환(중복은 제거됨)
  • max() : 집합에 있는 데이터 데이터 중 가장 큰 데이터 반환
  • min() : 집합에 있는 데이터 데이터 중 가장 작은 데이터 반환
  • sum() : 집합에 있는 데이터 데이터의 합을 반환(중복 제거한 후 총합)
  • sorted() : 집합 정렬 후 리스트로 반환하나 세트로 다시 변환하면 순서 잃음
  • 🔥 순서가 없기 때문에 revered() 사용 불가
  • add() : 인자로 넣은 데이터 1개를 집합의 원소로 추가
  • update([]) : 인자를 리스트 형태로 전달하여 다수의 데이터를 집합에 추가
    🔥 리스트(list)에서는 append()를 사용하지만, 집합(set)에서는 add()를 사용함
  • clear() : 원소를 모두 삭제함
  • discard() : 인자로 넣은 1개의 데이터를 집합에서 삭제(remove()로도 가능)

집합 자료형 또한 다른 자료형과 마찬가지로 다양한 함수가 존재한다.

 

하나의 집합 데이터에 값을 추가할 때는 add() 함수를 이용하고, 여러 개의 값을 한번에 추가하고자 할 때는 update() 함수를 사용한다.

 

또한 특정한 값을 제거할 때는 remove() 함수를 이용할 수 있다.

⇒ add(), remove() 함수 모두 시간 복잡도는 O(1) 이다.