본문 바로가기
관리자

Programming-[Backend]/Python

파이썬 중급 - 4. 해시테이블(Dictionary), Set

728x90
반응형

Dictionary

파이썬은 기본적으로 dict형을 제공하며, 해시 테이블 자료구조로 구현되어있기 때문에 따로 해시 테이블을 구현할 필요가 없다. 아래 명령어로 출력해보면 파이썬의 코드 자체가 dict형태로 구현된 것을 볼 수 있다.

print(__builtins__.__dict__)
# {'__name__': 'builtins', '__doc__': "Built-in functions, exceptions, and other objects.\\n\\nNoteworthy: None is the `nil' object; Ellipsis r.....

각 객체의 고유한 key값인 hash값은 hash() 함수로 확인할 수 있다. 다만 mutable한 자료형은 변경이 가능하므로 hash값을 확인할 수 없다.

t1 = (10, 20)
l1 = [10, 20)

print(hash(t1)) #124129512124
print(hash(l1)) #TypeError: unhashable type: 'list'

 

 

setdefault

코딩을 하다보면 key-value로 이루어진 구조를 dict형태로 재구성해야할 경우가 많다. 이 경우 setdefault 메서드를 사용하면 if문 없이 좀 더 깔끔하게 코딩이 가능하다. setdefault의 인자는 키 값, 새로 생성 시 value값에 매칭할 컬렉션 타입이다.

source = (('k1', 'val1'),
          ('k1', 'val2'),
          ('k2', 'val3'),
          ('k2', 'val4'),
          ('k2', 'val5'))

new_dict1={}
new_dict2={}

#No use setdefault
for k, v in source:
    if k in new_dict1:
        new_dict1[k].append(v)
    else:
        new_dict1[k] = [v]

#Use setdefault
for k, v in source:
    new_dict2.setdefault(k, []).append(v)

#check
print(new_dict1)
print(new_dict2)
# {'k1': ['val1', 'val2'], 'k2': ['val3', 'val4', 'val5']}
# {'k1': ['val1', 'val2'], 'k2': ['val3', 'val4', 'val5']}

dictionary comprehension 방식으로 만들면 중복된 키가 덮어써져 버리므로 주의해야한다.

new_dict3 = {k : v for k, v in source}
print(new_dict3)
#{'k1': 'val2', 'k2': 'val5'}

 

 

MappingProxyType

변경되지 않아야할 dictionary 값을 선언할 때 사용한다. 자바에서의 final과 같은 기능을 한다.

from types import MappingProxyType

d = {'key1': 'value1'}

#Read only
d_frozen = MappingProxyType(d)

print(d, id(d))
print(d_frozen, id(d_frozen))
#{'key1': 'value1'} 4348096704
#{'key1': 'value1'} 4348179216
#unhashable 값이라 hash()값 출력 불가

 

 

 

Set

set은 중복을 허용하지 않고 순서가 없다. dictionary처럼 frozenset을 선언하여 집합을 읽기 전용으로 만들 수 있다.

s1 = {'Apple', 'Orange', 'Apple', 'Orange', 'Kiwi'}
s2 = set(['Apple', 'Orange', 'Apple', 'Orange', 'Kiwi'])
s3 = {3}
s4 = set() # 그냥 {}를 선언하면 dict형이 된다.
s5 = frozenset({'Apple', 'Orange', 'Apple', 'Orange', 'Kiwi'})

s1.add('Melon')
print(s1) # {'Melon', 'Apple', 'Kiwi', 'Orange'}

#s5.add('Melon') #추가 불가

dis 모듈을 사용하면 실제 파이썬이 실행하는 바이트코드 실행문을 출력해볼 수 있다. 그냥 중괄호{}를 통해 set을 선언하는 것보다 set()메서드를 실행했을 때 바이트코드가 더 필요하다. 불필요하게 set() 메서드를 사용하지 않는 것이 최적화에 좋다.

 


참조

 

1. 인프런 강의 - 우리를 위한 프로그래밍 : 파이썬 중급 (Inflearn Original)

https://www.inflearn.com/course/%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%98%EB%B0%8D-%ED%8C%8C%EC%9D%B4%EC%8D%AC-%EC%A4%91%EA%B8%89-%EC%9D%B8%ED%94%84%EB%9F%B0-%EC%98%A4%EB%A6%AC%EC%A7%80%EB%84%90/dashboard

728x90
반응형