본문 바로가기

카테고리 없음

#파이썬 기초 5일차_2

728x90

Mapping & Set Data Type

  • 데이터를 효율적으로 관리하고 처리하기 위해 다양한 자료형이 사용된다. 그 중에서도 Mapping 자료형과 Set 자료형은 중요한 역할을 한다.

Mapping & Set 자료형 개요

  • Mapping 및 Set 자료형은 여러 개의 원소를 관리하고 처리할 수 있는 Collection 형태의 자료형으로, 이들은 데이터를 검색할 때 Index가 아닌 Key를 사용하여 접근하고 읽어 처리한다.
  • Key로 데이터를 검색하고 읽기 위해서는 Key의 유일성을 유지해야 하며, 이를 위해 Hash 알고리즘을 사용하여 유일한 값을 구성한다.

Mapping Data Type (매핑 자료형)

매핑 자료형은 Key와 Value(값)를 쌍으로 관리하는 자료형으로, 이러한 구조 덕분에 특정 Key에 해당하는 값을 빠르게 검색, 추가, 삭제할 수 있다.

종류

  • Dictionary (딕셔너리): 원소의 변경, 추가, 삭제가 가능하며, 가장 대표적인 매핑 자료형. Python에서 {} 또는 dict()로 생성할 수 있다.

Set Data Type (집합 자료형)

집합 자료형은 Key만으로 원소를 관리하는 자료형, 중복되지 않는 원소들로 구성되며, 수학의 집합 개념과 유사

종류

  • Set (셋): 원소의 변경, 추가, 삭제가 가능한 자료형. {} 또는 set()로 생성할 수 있으며, 유일한 원소들로 구성.
  • Frozenset (프로즌셋): 원소의 변경이 불가능한 불변 자료형. frozenset()으로 생성하며, 한 번 생성된 후에는 원소를 변경할 수 없다.

1. Dictionary

1.1 Dictionary의 Key 구성 및 생성 기준

 
  • Key의 유일성: Dictionary의 Key는 유일성을 유지하는 자료형만 지원되며. Key는 Hash 알고리즘을 통해 유일한 값으로 생성되고, Key의 중복을 방지하는 역할을 한다.
  • Key의 자료형: Key는 변경이 불가능한 자료형이어야 한다. 지원되는 자료형에는 int, float, tuple, str, bytes, frozenset 등이 포함되어있다.
  • Value의 자료형: Dictionary의 Value는 모든 자료형을 지원한다.
  • 쌍으로 구성: Dictionary는 항상 Key와 Value의 쌍으로 구성되어 있다

Key로 사용할 수 없는 자료형

  • 변경 가능한 자료형: List, Dictionary와 같은 변경 가능한 자료형은 Key로 사용할 수 없다. 이는 원소들이 변경되면 동일한 형태를 유지할 수 없기 때문이다.
  • 완전한 불변성을 유지하지 못하는 Tuple: Tuple도 Key로 사용할 수 있지만, Tuple의 일부 원소가 List일 경우 완전한 불변성을 유지할 수 없기 때문에 Key로 사용할 수 없는 것이다.

Dictionary의 Hash 알고리즘

Dictionary를 생성할 때 우리가 Key-Value를 입력한다. 이때 Key는 Hash 알고리즘을 통해 유일한 값으로 생성되는데, Dictionary가 Key를 관리하기 위한 Hash 구조를 별도로 생성하기 때문이다.

이 구조를 기반으로 다양한 값을 가진 인스턴스와 1:1 매핑된 구조가 만들어지며. 이러한 1:1 형태의 매핑 구조를 유지하기 때문에 Key가 중복되지 않게 관리되는 것이다.

Key를 구성하는 Hash의 기본 정보

Python에서는 Hash 관련 정보를 sys 모듈의 hash_info 속성에서 관리.

  • width: Hash 값에 사용되는 비트의 너비.
  • hash_bits: Hash 알고리즘의 내부 출력 크기.
  • seed_bits: Hash 알고리즘의 Seed Key 크기.
  • inf: 양의 무한대에 대한 Hash 값.
  • nan: NaN(Not a Number)에 대한 Hash 값.
  • algorithm: Hash 알고리즘의 이름. (지원되는 자료형: str, bytes, memoryview)
import sys

print(sys.hash_info.width)
print(sys.hash_info.hash_bits)
print(sys.hash_info.seed_bits)
print(sys.hash_info.inf)
print(sys.hash_info.nan)
print(sys.hash_info.algorithm)

64
64
128
314159
0
siphash24

 

.2 Dictionary 생성하기

  • 빈 Dictionary 생성하기
  • 딕셔너리의 경우 변형 가능하기 때문에 이대로 생성하면 됨

방법1)

d = {}
print(type(d),d)

<class 'dict'> {}

 

방법2)

dc = dict()
print(type(dc),dc)

<class 'dict'> {}

  • 키워드 인자에 동일한 Key를 중복시킬 경우
  • 기본적으로 키는 중복되면 안됨
d = dict(a=10,b=20,a=20)

SyntaxError: keyword argument repeated: a

 

# 키워드 인자의 이름을 변경하면 값이 같더라도 키가 다르면 생성 가능

d = dict(a=10, b=20, c=20)
print(d)

{'a': 10, 'b': 20, 'c': 20}

  • Tuple 원소 List로 동일한 Key를 중복시킬 경우
  • Tuple의 구성이 다르기때문에 예외가 발생하지 않음. 대신 키가 같으면 나중에 들어온 것으로 대체됨(덮어버림)
 
l = [('a',1),('b',2),('a',3)]

d = dict(l)
print(d)

{'a': 3, 'b': 2}

  • Dictionary의 Key에 대한 처리 방식
d = {'name': 'John', 'age': 30 }
print(type(d), d)

<class 'dict'> {'name': 'John', 'age': 30}

d = {1: 'apple', 2: 'ball'}
print(type(d), d)

<class 'dict'> {1: 'apple', 2: 'ball'}

d = {'name': 'John', 1: [2, 4, 3]}
print(type(d), d

<class 'dict'> {'name': 'John', 1: [2, 4, 3]}

  • bytes, frozenset을 Key로 사용하는 경우 (불변의 데이터)
b = bytes(b'123')
d = {b:1}
print(d)

{b'123': 1}

 

forzenset : 변경 불가능

b = frozenset([1,2,3])
d = {b:1}
print(d)

{frozenset({1, 2, 3}): 1}

 

2.2 Tuple 원소를 가진 List 인자

# using dict()
my_dict = dict({1:'top', 2:'class'})
print(my_dict)

{1: 'top', 2: 'class'}

 

수정 가능한 리스트 형태로 들어옴(우리가 수정할 수 없는 튜블이 들어간 데이터)

my_dict1 = dict([(1,' top '), (2,' class ')])
print(my_dict1)

{1: ' top ', 2: ' class '}

  • List나 Tuple을 이용해서 Key만 생성하기
l = [1,2,3,4]
d = {}
d = d.fromkeys(l) # 비어있는 딕셔너리 . fromkeys(),  l에 들어있는 내용을 키로 받아온다는 것
print(d)

{1: None, 2: None, 3: None, 4: None} # none이라는 데이터가 들어있다 생각해야함

 

t = (1,2,3,4)
d = {}
d = d.fromkeys(t)
print(d)

{1: None, 2: None, 3: None, 4: None}

 

a = (1,2,[1,2])
d = {}
d.fromkeys(a)

TypeError: unhashable type: 'list' # 리스트는 키로 쓸수 없기 때문에 에러 발생함

 

2.3 Dictionary에 요소 추가하기

d = {1:1,2:2}
d2 = dict([("a",'top'), ("b",'class')])

d.update(d2)
print(d)

{1: 1, 2: 2, 'a': 'top', 'b': 'class'}

d = {1:1,2:2}
d2 = dict([("a",'top'), (1,'class')])

d.update(d2)
print(d)

{1: 'class', 2: 2, 'a': 'top'}

 

 

enumerate 함수는 반복 가능한 객체(iterable)를 인덱스(index)와 해당 인덱스에 대한 값을 동시에 얻을 수 있는 기능, 한마디로 인덱스의 인덱스와 벨류를 동시에 얻게해줌

solar1 = ['태양', '수성', '금성', '지구', '화성', '목성', '토성', '천왕성', '해왕성']
solar2 = ['Sun', 'Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune']
solardict = {}

for i, k in enumerate(solar1):
   val = solar2[i]
   solardict[k] = val

print(solardict)

{'태양': 'Sun', '수성': 'Mercury', '금성': 'Venus', '지구': 'Earth', '화성': 'Mars', '목성': 'Jupiter', '토성': 'Saturn', '천왕성': 'Uranus', '해왕성': 'Neptune'}

 

2.4 Dictionary의 특정 요소 값 변경하기

names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, 'Michale':27115, 'Bob':5887, 'Kelly':7855}
names['Aimy'] = 10000
print(names)

{'Mary': 10999, 'Sams': 2111, 'Aimy': 10000, 'Tom': 20245, 'Michale': 27115, 'Bob': 5887, 'Kelly': 7855}

 

2.5 Dictionary의 특정 요소 제거하기

del names['Sams']
print(names)

{'Mary': 10999, 'Aimy': 10000 , 'Tom': 20245, 'Michale': 27115, 'Bob': 5887, 'Kelly': 7855}

 

예시)

my_dict = {}

for i in range(10) :
    my_dict[i] = i
print(my_dict)

{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8, 9: 9}

d = my_dict.popitem()
print(d) 
print(my_dict)

(9, 9)  # 따로 지정하지 않아서 가장 마지막 키 벨류가 튀어나옴

{0: 0, 1: 1, 2: 2, 3: 3, 4: 4, 5: 5, 6: 6, 7: 7, 8: 8}

 

딕셔너리는 기본적으로 인덱스가 없음

my_dict = {}

for i in range(10) :
    my_dict[str(i)] = i
print(my_dict)

{'0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

f1 = my_dict.pop('1') # 1이라는 값을 줌(인덱스 1)
print(f1)
print(my_dict)

1

{'0': 0, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9}

 

2.6 Dictionary의 모든 요소 제거하기

names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, 'Michale':27115, 'Bob':5887, 'Kelly':7855}
names.clear()
print(names)

{}

 

2.7 Dictionary에서 Key만 추출하기

예시 1)

d = dict([('a',1),('b',2)])

keys = d.keys()
print(type(keys), keys)

<class 'dict_keys'> dict_keys(['a', 'b'])

 

iter 함수는 반복 가능한 객체(iterable)에서 이터레이터(iterator)를 반환합니다.

next 함수는 이터레이터에서 다음 값을 반환(현재 기준으로)

 

keys = iter(keys)
print(next(keys))
print(next(keys))
print(next(keys))

a

b

StopIteration: # 더이상 값이 없으므로 에러가남

  • for문을 사용해서 key만 들고오게 해도 key만 추출가능하다.(keys 이용)
l = [('a',1), ('b',2)]
d = dict(l)
print(d.keys())

for i in d.keys() :
    print(i)

dict_keys(['a', 'b'])

a

b

print(list(d.keys()))

['a', 'b']

 

names = {'Mary':10999, 'Sams':2111, 'Aimy':9778, 'Tom':20245, 'Michale':27115, 'Bob':5887, 'Kelly':7855}
ks = names.keys()
print(ks)

for k in ks:
   print('Key:%s \tValue:%d' %(k, names[k]))

dict_keys(['Mary', 'Sams', 'Aimy', 'Tom', 'Michale', 'Bob', 'Kelly'])
Key:Mary  Value:10999
Key:Sams  Value:2111
Key:Aimy  Value:9778
Key:Tom  Value:20245
Key:Michale  Value:27115
Key:Bob  Value:5887
Key:Kelly  Value:7855

728x90