본문 바로가기

프로그래밍/알고리즘

[방학의 PS] set, deque, 리스트의 참조 복사

오늘은 원래 DFS와 BFS를 공부하고자 하였으나, 몇 가지 추가적인 공부가 필요하여 이를 보충하도록 하겠습니다.

 

1. set

 

set은 파이썬의 데이터 타입입니다. 딕셔너리나 리스트와 같이 말입니다. 이는 수학에서 집합과 매우 유사한 특징을 지니는데, 우선 다음과 같이 선언 및 정의하게 됩니다.

s1 = set([1, 2, 3, 3])    # [1, 2, 3, 3]이라는 리스트를 set 자료형으로 바꿔 s1에 저장한다는 의미입니다.
s1
>> {1, 2, 3}

set의 중요한 특징은 다음과 같습니다.

 

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

위의 코드에서 보신 것처럼 set은 중복을 허용하지 않습니다. 또한 순서가 존재하지 않는데, 이는 인덱스로 접근할 수 없다는 것을 의미합니다. 예를 들면 s1 [1]과 같이 입력할 경우 TypeError를 반환합니다. set의 경우 다음과 같은 재미있고 유용한 기능들이 있습니다.

s1 = set([1, 2, 3])
s2 = set([2, 3, 4])

s1 & s2   # 합집합
>> {1, 2, 3, 4}
s1 | s2   # 교집합
>> {2, 3}
s1 - s2   # 차집합
>> {1}

s1.add(5)   # 하나의 원소 추가
s1
>> {1, 2, 3, 5}

s2.update([7, 8])    # 여러 개의 값 추가
s2
>> {2, 3, 4, 7, 8}

s2.remove(2)   # 값 삭제
s2
>> {3, 4, 7, 8}

모든 것을 자세히 설명드리지 못해 죄송하지만, update라는 기능이 무척 재미있는 것 같습니다.

 

 

2. deque

 

또 하나의 자료형은 바로 데크(deque)입니다. deque는 다음과 같이 사용합니다.

from collections import deque    # 불러오는 과정이 필요합니다!

deq = deque([1, 2, 3])
deq
>> deque([1, 2, 3])

deq.append(4)
deq
>> deque([1, 2, 3, 4])

deq.appendleft(0)
deq
>> deque([0, 1, 2, 3, 4])

deq.pop()
>> 4

deq.popleft()
>> 4

즉, deque는 양쪽에서 모두 자료를 넣었다 뺄 수 있는 자료형입니다. 이때의 연산은 파이썬의 list보다 훨씬 효율적으로 이루어지는 것으로 알고 있습니다.

 

 

3. 개인적인 의문

 

다음 코드는 오늘 문제를 구현하다 맞닥뜨리게 된 제 개인적인 의문이었습니다.

g1 = [[]] * 3
g1
>> [[], [], []]

g2=[[] for _ in range(3)]
g2
>> [[], [], []]

g1[0].append(1)
g1
>> [[1], [1], [1]]

g2[0].append(1)
g2
>> [[1], [], []]

두 결과가 왜 다르게 반환될 까요? 아무래도 g1은 내부의 리스트가 참조 복사되는 반면, g2의 경우 내부의 리스트가 별개의 리스트로 지정된 것 같습니다.