Home [2021 인공지능전문가 교육과정 복습] 매핑, 딕셔너리, 집합, any(), all()
포스트
취소

[2021 인공지능전문가 교육과정 복습] 매핑, 딕셔너리, 집합, any(), all()

매핑(Mapping)

키(key) 값(value) 쌍

추상자료형

속성

  • 키 데이터와 값 데이터를 짝지어 저장한다.
  • 변형이 불가능한 임뮤터블(immutable) 자료형 만 키(key) 가 될 수 있다.

연산

  • 각 값(value) 데이터는 키(key) 로만 접근할 수 있다.

매핑 예

딕셔너리


매핑 - 딕셔너리(Dictionary)

대표적인 매핑 타입 자료구조다.

추상자료형

  • 매핑의 속성, 연산 상속

딕셔너리 만의 연산

  • clear(): 딕셔너리 내 모든 항목을 삭제할 수 있어야 한다.
  • copy(): 딕셔너리 복사본을 반환한다.
  • get(key): 키에 해당 하는 값을 리턴한다. 값이 없으면 None을 리턴한다.
  • update(dict): dict의 키와 값의 목록을 dict에 추가한다. (또는 키-값 pair 를 dict로 수정)
  • items(): 딕셔너리 내 모든 키-값 쌍을 튜플로 묶어서 반환한다.
  • keys(): 키 목록을 반환한다.
  • values(): 값 목록을 반환한다.
  • popitem(): 요소 중 가장 오른쪽에 위치한 pair 삭제 후 반환한다. OrderedDict 이면 popitem() 안에 last=True 또는 False 로 각각 맨 마지막 순서 pair 를 삭제하거나 맨 처음 pair 삭제할 수 있다.
  • pop(key): 특정 key의 value 반환 후 그 pair 삭제한다.

딕셔너리 구현 방법

  • 해시 테이블

딕셔너리 생성하기 - dict() 또는 {} 이용하는 방법

1
2
# 빈 딕셔너리 생성 
dd = dict()
1
2
# 또는
dd = {}

setdefault() 로 특정 키의 기본값 지정하기

  • dict_name.setdefault(key, 값)
1
2
dd.setdefault(3, 'hello')
dd

Screen Shot 2022-01-07 at 21 18 11

setdefault() 에 지정해 준 key값을 딕셔너리가 이미 갖고 있는 경우

그 key값에 원래 할당되어 있던 값을 출력한다.

1
2
a = {'a':3,'b':8}
a.setdefault('a',8)

출력: 3

setdefault() 에 key값만 넣는 경우

그 key값의 기본값으로 None 이 할당된다.

1
2
3
dd = {}
dd.setdefault(3) # 3이 key 된다. 
dd

Screen Shot 2022-01-07 at 21 24 08


딕셔너리 생성하기 - Defaultdict Class 이용하는 방법

정의: 기본값 갖는 딕셔너리 만드는 클래스.

1
2
3
from collections import defaultdict

dd = defaultdict(객체 이름, key=value1, key=value2,...)
  • collections 모듈에서 defaultdict 를 불러와서 사용한다.
  • 기본 딕셔너리 는 자신이 포함하고 있지 않은 키 값이 들어오면 key error를 발생시킨다.
  • 하지만 defaultdict 는 딕셔너리 기본값을 지정해줌으로써, 없던 키 값이 들어오면 기본값을 출력하고, 그 키 값에도 기본값 할당해준다.
  • 결국 예상치 못한 key 값 들어왔을 때 key error 발생하는 걸 막을 수 있다.

defaultdict ‘객체 이름’ 자리에 넣은 객체 기본값이 ‘기본값’이 된다.

예를 들어 int를 넣으면 0을 기본값으로 설정한다. list 를 넣으면 [] 가 기본값이 된다.

한편 key= argument를 써서 ‘키 = 값’ 을 넣어줄 수도 있다. 이건 딕셔너리 생성하면서 특정 키-값 쌍을 같이 만들기 위한 것이다.

1
2
dd = defaultdict(list)
dd

Screen Shot 2022-01-07 at 21 26 11

defaultdict(기본값, 현재 딕셔너리 상태) 가 출력된다.

객체 자리에 list를 넣었으므로, 기본값은 [] 빈 리스트가 된다.

1
dd[3] # 빈 딕셔너리에 3이 가지고 있는 값 출력 요구 

Screen Shot 2022-01-07 at 21 28 18

기본값 빈 리스트 출력한다.

그리고 딕셔너리를 확인해보면 key 3이 [] 빈 리스트를 값으로 갖고 있는 걸 볼 수 있다.

Screen Shot 2022-01-07 at 21 29 23

만약 기본값 자리에 문자열 str 객체를 넣으면 ‘’ 공백이 기본값 된다.

1
2
3
dd = defaultdict(str, a=[1,2],b=3)
dd[6]
dd

Screen Shot 2022-01-07 at 21 36 29


딕셔너리 생성하기 - OrderedDict Class 이용하는 방법

정의: key값 순서 기억하는 딕셔너리 만드는 클래스.

쓸모: 딕셔너리로 for문 돌 때 ‘시퀀스 타입처럼’ 일정한 순서 가지고 데이터에 접근할 수 있다.

*하지만 파이썬 업데이트 후 기본 딕셔너리도 반복문 돌 때 일정 순서 유지하게 되면서, 별로 안 쓰인다.

1
2
3
4
5
6
7
8
from collections import OrderedDict

od1 = OrderedDict({'a':1, 'b':2,'c':3})

for i in od1 : 
    print(f'key:{i}')
    print(f'value:{od1[i]}')
    print('-'*3)

Screen Shot 2022-01-07 at 21 53 50

key값 순서기억

1
2
3
4
5
6
7
od1 = OrderedDict({'a':1, 'b':2,'c':3})

od2 = OrderedDict({'a':1, 'c':3, 'b':2})
print(od1 == od2)

od3 = OrderedDict({'a':1, 'b':2, 'c':3})
print(od1 == od3)

False

True

key 순서가 같아야 두 딕셔너리 같다고 하는 걸 볼 수 있다.

기본 딕셔너리는 순서 개념 자체가 없어서 키-값 쌍만 모두 같으면 같은 딕셔너리로 분류된다.


딕셔너리 정렬하기

sorted() 를 사용해서 딕셔너리를 정렬할 수 있다.

1
sorted(딕셔너리.items(), key=정렬기준) # 정렬 기준은 lambda 함수 써서 지정한다.

OrderedDict 정렬시키기

1
2
3
4
5
d = OrderedDict({'milk':3, 'coffee':1, 'capuchino':4, 'tea':2})

print(OrderedDict(sorted(d.items(), key=lambda x : x[1]))) # value를 기준으로 정렬
print(OrderedDict(sorted(d.items(), key=lambda x : x[0]))) # key를 기준으로 정렬 
print(OrderedDict(sorted(d.items(), key=lambda t : len(t[0])))) # 영단어 알파벳 길이 순 정렬

Screen Shot 2022-01-07 at 22 44 21

기본 딕셔너리 정렬시키기

1
2
3
4
d2 = dict(d) # 기본 딕셔너리로 만들기 
print(dict(sorted(d2.items(), key=lambda x : x[0]))) # key 기준으로 정렬
print(dict(sorted(d2.items(), key=lambda x : x[1]))) # value 기준으로 정렬
print(dict(sorted(d2.items(), key=lambda x : len(x[0])))) # key 알파벳 길이 짧은 순 오름차순 정렬

Screen Shot 2022-01-07 at 22 42 54


집합(Set)

구별가능한 개체들의 모임

  • 딕셔너리에서 key만 모아놓은 형태

추상자료형

속성

  • 요소(element) 간 중복 안 된다.
  • 각 요소 별 key 도, 순서(인덱스)도 없다. (따라서 인덱싱도, 슬라이싱도 불가능하다)

연산

  • add(x): 집합 내에 특정 원소 x를 추가한다.
  • discard(x): 집합 내 특정 원소 x를 삭제한다.
  • clear(): 집합 내 모든 원소를 삭제한다.
  • union(s): s와의 합집합 새로 생성한다.
  • difference(s): s와의 차집합 새로 생성한다. 두 집합에 대한 - 연산과 같다.
  • intersection(s): s와의 교집합 새로 생성한다. 두 집합에 대한 & 연산과 같다.
  • symmetric_difference(s): s와의 대칭 차집합 새로 생성한다. 두 집합에 대한 ^ 연산과 같다.
  • issubset(s): 다른 집합 s의 부분집합인지 검사한다. True 또는 False 반환한다.
  • issuperset(s): 다른 집합 s를 포함하는지 검사한다. True 또는 False 반환한다.
  • isdisjoint(s): s 집합과 교집합이 하나도 없는지 검사한다. True 또는 False 반환한다.

집합 구현 방법

  • 해시 테이블

집합의 효율성

집합은 데이터 소속검사에서 리스트보다 빠르다(효율적이다)

  • 집합은 소속검사에 $O(1)$ 만큼 시간복잡도 걸린다.
  • 리스트는 소속검사에 $O(n)$ 만큼 시간복잡도 걸린다.

리스트는 요소들에 하나하나, 일일이. 순차접근해서 소속검사를 하는 데 반해, 집합은 해시 테이블 이용해서 한방에 소속검사 하기 때문이다.

어떤 값에 대해 소속검사 명령이 들어오면, 집합은 그 값을 해시 함수에 통과시켜 해시 값을 얻는다. 그 해시 값을 주소로 해시 테이블에 접근해서 저장소에 True 가 저장되어 있는지, False가 저장되어 있는지 확인한다. 이렇게 한 번만 검사하면 값 소속 여부를 바로 알 수 있기 때문에, $O(1)$ 만큼 시간 복잡도가 걸린다.

[출처: https://rexiann.github.io/2020/11/28/set-in-python.html ]

1
2
3
4
5
6
# 집합은 리스트보다 소속검사 속도가 월등히 빠르다

set1 = {'k1', 'k2', 'k3', 'k4'}

'k1' in set1 # True
'k5' not in set1 # False

집합은 데이터 삽입, 삭제에서 배열로 구현된 리스트보다 빠르다(효율적이다)

  • 집합은 삽입, 삭제에 $O(1)$ 만큼 시간 복잡도 걸린다.
  • 배열로 구현된 리스트는 삽입, 삭제에 $O(n)$ 만큼 시간 복잡도 걸린다.

배열로 구현된 리스트는 데이터를 삽입, 삭제하면 각 항목들의 물리적 이동이 동반된다.

예를 들어 0번 인덱스 항목을 삭제하면 그 뒤의 1,2,3,… 번 인덱스 항목들이 앞으로 한 칸씩 물리적 이동한다. 따라서 시간복잡도가 $O(n)$ 만큼 걸린다.

하지만 집합은 해시 테이블 사용하기 때문에 삽입, 삭제에 $O(1)$ 만큼 시간복잡도 걸린다.

어떤 값을 삽입 할 때는 해시함수로 그 값의 해시를 받아서, 저장소에 해시와 True 만 저장하면 될 것이다.

어떤 값을 삭제 할 때는 그 값의 해시(주소)에 접근해서 저장소에 True를 False 로 바꾸면 될 것이다.

결국 삽입을 하든 삭제를 하든 $O(1)$ 만큼 시간복잡도만 걸린다.

$\Rightarrow$ 리스트에 소속검사, 삽입, 삭제가 빈번하게 일어날 경우 리스트를 집합으로 변환해서 사용하는게 효율적이다.


all() 과 any()

반복가능자를 입력으로 받아서. 검사한 뒤 결과를 True / False 로 반환하는 논리연산 함수.

all()

  1. 반복가능자 입력받는다.
  2. 요소가 모두 0 또는 ‘’ 공백 문자열이 아닐 때 True 반환한다. 하나라도 0 또는 ‘’ 가 있으면 False 반환한다.
  3. 만약 반복자가 비어있으면 True 반환한다.
1
2
3
4
5
6
7
8
# all(): 0 또는 공백이 모두 아닐 때 true

s1 = {1,2,3}
s2 = {''}
s11 = [1,2,3]
all(s2) # False 반환한다
all({}) # True 반환한다
all(s11) # True 반환한다

any()

  1. 반복가능자 입력받는다.
  2. 요소 중에 0 또는 ‘’ 공백 문자열 아닌 게 하나라도 있으면 True 반환한다.
  3. 요소가 모두 0 또는 ‘’ 공백 문자열 일 때 만 False 반환한다.
  4. 만약 반복자가 비어있으면 False 반환한다.
1
2
3
4
5
6
# any(): 0 또는 공백이 아닌게 하나라도 있으면 true

s3 = {0,"",1}
s4 = {}
any(s3) # 1 때문에 True 
any(s4) # False

sorted() 함수로 집합 정렬시키기

집합은 순서가 없다. 따라서 정렬이 불가능하다.

sorted() 함수는 반복가능자를 입력받아, 일단 리스트로 바꾸고 정렬시켜 결과값을 출력한다.

집합도 반복가능자 이므로 sorted() 함수에 넣을 수 있다.

다만 결과가 리스트로 바뀌어 나오므로, sorted(집합) 한 결과를 다시 집합으로 바꿔야 한다.

이게 집합을 정렬시키는 방법이다.

  • sorted(반복가능자, key=lambda 함수(정렬기준), reverse=True)
1
2
3
4
5
# sorted() 함수로 집합 정렬시키기

s1 = {'key1', 'key2', 'key3'}

sorted_s1 = sorted(s1, reverse=True)

Screen Shot 2022-01-08 at 17 35 54

보다시피 리스트로 정렬된 채 출력된다.

집합으로 사용하려면 다시 집합으로 바꿔줘야 한다.

1
2
3
4
# sorted() 결과를 다시 집합으로 바꾸기 

s2 = set(sorted_s1)
s2

Screen Shot 2022-01-08 at 17 37 46

[2021 인공지능전문가 교육과정 복습] 시퀀스, 리스트, 튜플, zip함수

[통계학개론 복습] 회귀분석 개념, 종류, 단순선형회귀분석, 다중선형회귀분석