1. 리스트에 넣어서 확인하기

li = list()
...
if "A" in li:
	...

in 연산자가 리스트 자료구조를 대상으로 동작할 때는, 리스트를 맨 앞에서부터 끝까지 순차적으로 탐색(선형 탐색)하기 때문에 시간 복잡도가 리스트의 길이(N)만큼 걸립니다. 따라서 해당 방식은 리스트가 고정적으로 짧은 길이인 경우에만 사용할 수 있습니다. → 권장 X

2. set에 넣어서 확인하기

st = set()
...
if "A" in st:
	...

in 연산자가 set 자료구조를 대상으로 동작할 때는, 다음과 같이 동작한다고 하였습니다.

“A” in st → hash(A) → 특정한 숫자 → st[특정한숫자]가 존재하는가?

이렇게 hash 함수 덕분에 O(1)에 근접하는 속도를 갖는다고 하여서 빠르게 탐색할 수 있습니다. → 권장 O

3. 비트 마스크를 통해서 확인하기

비트 마스크란 비트 연산을 이용하여서 특정한 데이터 쌍을 표현하는 방식입니다.

간단하게 예를 들어, 1~5까지의 숫자를 내가 이미 갖고 있는지를 자료형으로 담아본다고 가정해보겠습니다.

경우 비트 마스킹
아무것도 없음 00000
1만 있음 00001
5만 있음 100000
1, 3 있음 00101
전부 있음 11111

이렇게 숫자 5개를 통해서 어떤 숫자들을 가지고 있는지를 표현할 수 있습니다. 이러한 비트로 작성된 자료형은 실제로 정수형으로 변경이 되기 때문에 메모리 측면에서 매우 적게 차지합니다.

비트 마스크에 값을 추가하는 것과 내가 이미 갖고 있는 값인지를 파악하는 것은 다음과 같이 수행합니다.

비트 마스크에 값을 추가하는 것

# bt의 3번째 비트를 1로 바꾸고자 한다.
bt = 33 # 100001
bt = bt | ( 1 << 3 )
# bt 와 ( 1 << 3 )을 OR 연산한다.
# 100001 | 100
# 100101

비트 마스크에서 값이 존재하는지 파악하는 것

# bt의 3번째 비트가 존재하는지 파악하려고 한다.
bt = 37 # 100101
result = bt & ( 1 << 3 )
# bt와 ( 1 << 3 )를 AND 연산한다.
# 100101 & 000100
# 3번째 자리 수를 제외한 값들은 영향을 주지 않는다.

비트 마스크에서 값을 제거하는 것

# bt의 3번째 비트를 0으로 바꾸고자 한다.
bt = 37 # 100101
bt = bt & ~(1 << 3)
# bt 와 ~( 1 << 3 )을 AND 연산한다.
# 100001 & ~(000100)
# 100101 & 111011
# 3번째 자리수만 반드시 0으로 바뀌고, 나머지는 유지된다.

비트 마스크에서 값을 토글하는 것