본문 바로가기

Programming/CxO를 위한 코딩

04-2 딕셔너리(dict)

반응형

앞 페이지에서 리스트(list)에 대해 알아봤습니다.

 

a = [1, 3, 5, 7, 9]

 

'10보다 작은 홀수' 혹은 '어떤 학생에 대한 국어/영어/수학 점수'처럼, 여러 개의 값들을 뭉치로 다룰 수 있는 것이 '리스트'였습니다.

 

그런데, `학생 A의 국어/영어/수학 점수, 학생 B의 국어/영어/수학 점수,...'처럼 100명의 학생에 대한 점수들을 다뤄야 한다면 어떻게 할까요?

 

'학생 A'에 대응하는 `국/영/수 점수`, '학생 B'에 대응하는 `국/영/수 점수` 같은 자료가 만들어져야 할 것입니다. 이러한 처리가 가능하도록 만들어진 자료형이 딕셔너리(Dictionary)입니다.

 

 


1. 생성하기 (Create)

비어있는 딕셔너리 만들기

a = {}

딕셔너리는 중괄호를 이용해서 만듭니다. (리스트는 대괄호를 사용합니다. a = [] )

 

혹은 직접 클래스 이름을 지정해서 만들 수도 있습니다.

 

a = dict()

이렇게 비어있는 딕셔너리를 만들고 난 후 아래와 같이 값을 지정해서 넣을 수 있습니다.

 a['A'] = 80

 


값을 지정해서 딕셔너리 생성하기

딕셔너리의 각 원소는 Key : Value로 구성됩니다.  여기서 Key 값은 다른 Key 값과 중복되지 않아야 하고, 콜론(:)에 의해 KeyValue 값이 구분됩니다.

 

학생별국어성적 = {'A':80, 'B':90, 'C':100}

 

이 코드가 동작하는 것을 설명해보면,

  • 각 학생별 국어 점수로 구성된 딕셔너리가 생성되고,
  • 이 딕셔너리가 '학생별국어성적'이란 변수에 할당되었습니다.

딕셔너리의 Key는, 위에서처럼 '문자'만 쓸 수 있는 것은 아닙니다. 다른 Key와 중복되지만 않는다면 정수든 문자열이든 어떤 자료형이어도 됩니다. 만약 동일한 Key가 있다면, 뒷부분에 정의된 값으로 할당됩니다.

 

a = {1:80, 2:60}
b = {1:80, 1:70} # b[1]=70이 됨

 


2. 읽기 (Read)

Key를 이용해서 Value 읽기

딕셔너리의 Key를 이용해서, 해당 Key에 해당하는 Value를 읽을 수 있습니다.

 

    value = 딕셔너리변수이름[key값]

 

혹은,

 

   value = 딕셔너리변수이름.get(key값)

 

학생별국어성적 = {'A':80, 'B':90, 'C':100}
print(학생별국어성적['A']) # 80
print(학생별국어성적.get('A') # 80

 

dic라는 딕셔너리에 대해서 'A'라는 Key값을 이용해서 Value 값을 읽는 방법이 두 가지입니다. 하나는 dic['A'], 다른 하나는 dic.get('A')

둘 다 Key 값이 'A'인 Value를 가져오는데, 다른 점은, 해당 Key가 없을 때의 동작입니다.

만약 읽으려는 Key 값 'Z'가 딕셔너리에 없다면,
  print(dic['Z'])  --> error 발생하고 코드 실행 멈춤

  print(dic.get['Z'])  --> 'None' 출력

따라서, Key값이 없을 때 에러가 나서 코드가 멈추게 하고자 한다면 dic[key값] 형태로, 그렇지 않고 None 값을 리턴하고 코드는 그대로 진행하게 하려면 dic.get[Key값]과 같이하면 됩니다.

해당 Key 값이 존재하는지 조사하기: in

어떤 Key값이 딕셔너리에 존재하는지 확인할 때는 'in'을 사용합니다. 존재하면 True를, 아니면 False 값을 리턴합니다.

 

    <key 값> in <딕셔너리 변수 이름>

 

if ('A' in 학생별국어성적):
    print("A가 존재")
else:
    print("A 없음")

모든 Key값 읽기: keys()

 

앞에서 살펴본 리스트(list)는 인덱스 번호를 이용해서 값을 읽을 수 있었으나, 딕셔너리는 인덱스 번호를 이용해서 값을 읽을 수 없고, Key 값을 알아야 합니다. 

딕셔너리에 어떤 Key값들이 있는지는 'keys()' 메서드를 이용하면 됩니다.

 

아래 코드는 모든 Key를 읽는 코드입니다.

학생별국어성적 = {'A':80, 'B':90, 'C':100}
for key in 학생별국어성적.keys():
    print(key) # A B C

 

알아낸 Key를 이용해서, 모든 Key에 대응하는 Value를 읽을 수 있습니다.

학생별국어성적 = {'A':80, 'B':90, 'C':100}

for key in 학생별국어성적.keys():
    print(학생별국어성적[key])  # 80 90 100

 


Value를 직접 읽기: values()

Key값을 모르더라도 직접 Value 값을 읽을 수 있습니다. 'values()' 메서드를 이용하면 딕셔너리에 있는 모든 Value 값들을 읽어 낼 수 있습니다.

 

학생별국어성적 = {'A':80, 'B':90, 'C':100}

for value in 학생별국어성적.values():
    print(value) #80 90 100

(Key, Value) 쌍 얻기: items()

items() 메서드를 사용하면 모든 Key와 Value를 (Key, Value)의 쌍으로 얻어낼 수 있습니다.

 

학생별국어성적 = {'A':80, 'B':90, 'C':100}
for (key, value) in 학생별국어성적.items():
    print(key,value)  # A 80  B 90   C 100

 


3. 수정하기 (Update)

딕셔너리에 Key와 Value값을 집어넣으려면 '딕셔너리변수이름[Key값]=Value값'과 같이 하면 됩니다.

 

아래 코드는 '학생별국어성적'이라는 비어있는 딕셔너리를 만들고 나서, 위의 방법으로 값을 집어넣는 코드입니다.

 

학생별국어성적={}
학생별국어성적['A'] = 80
학생별국어성적['B'] = 90
학생별국어성적['B'] = 100

 

만약 이미 존재하는 Key값과 동일한 Key값을 다시 지정했다면, 기존에 있던 값 위에 새로운 값이 덮어 쓰이게 됩니다. 즉, 해당 Key값에 대응하는 Value값이 새로운 값으로 바뀌게 됩니다.

학생별국어성적 = {'A':80, 'B':90, 'C':100}
print(학생별국어성적['A']) #80

학생별국어성적['A']=20
print(학생별국어성적['A']) #20

4. 삭제하기 (Delete)

딕셔너리의 한 원소를 삭제하는 것은 'del 딕셔너리변수이름[Key값]'과 같이 하면 됩니다.

학생별국어성적 = {'A':80, 'B':90, 'C':100}
print(학생별국어성적['A']) # 80

del 학생별국어성적['A']
print(학생별국어성적['A']) # error

 


5. 연습 문제

문제 1. 

4명의 학생의 국/영/수 성적이 다음과 같다. 

  훈요 : 100/100/55
  화서 : 90/90/85
  영하 : 80/100/80
  지니 : 80/70/100  

각 학생의 이름을 Key로하고, 국/영/수 점수 리스트를 Value로하는 딕셔너리를 '성적'이라는 변수로 만들고, print(성적) 해보세요.

 

 

정답은,

더보기
성적 = {
    '훈요':[100, 100, 55],
    '화서':[90, 90, 85],
    '영하':[80, 100, 80],
    '지니':[80, 70, 100],
}
print(성적)

 

 

아래와 같이 짤 수도 있습니다.

더보기
성적 = {}
성적['훈요'] =[100, 100, 55]
성적['화서'] = [90, 90, 85]
성적['영하'] = [80, 100, 80]
성적['지니'] =[80, 70, 100]
print(성적)

 

문제 2. 

위 문제1에서 만든 '성적' 딕셔너리를 이용해서, 각 학생의 평균을 구하고, 각 학생을 Key로하고, 그 학생의 평균을 Value로 하는 '평균'이라는 새로운 딕셔너리를 만들고, print(평균) 해보세요.

 

<힌트>

딕셔너리에서 (key, value) 쌍으로 읽어내는 메서드는 items() 입니다. 

 

정답은,

더보기
평균 = {}
def 평균계산(value_list):
    sum = 0
    for v in value_list:
        sum += v
    return sum / len(value_list)

for (key,value) in 성적.items():
    평균[key] = 평균계산(value)

print(평균)

 

문제 3.

문제 2의 '평균' 딕셔너리를, 각 학생의 평균값이 높은 순으로 정렬하고, 평균이 높은 학생 이름 순서로 '학생순위'라는 리스트를 만들고, print(학생순위) 해보세요. 

<힌트>

딕셔너리의 value 순으로 정렬하는 방법을 알기 위해서 'python dictionary sort value'라는 키워드로 구글링 해봅니다.

 

정답은, 

더보기
평균정렬 = sorted(평균.items(), key=lambda x: x[1], reverse=True)
print(평균정렬)

학생순위 = [k[0] for k in 평균정렬]

print(학생순위)

sorted 함수는 리스트, 딕셔너리, 튜플 데이터를 정렬한 후 새로운 리스트를 만들어서 리턴합니다.

일반적인 사용법은, 

 

  정렬된_리스트 = sorted(정렬할_자료, key=정렬 기준되는 값을 리턴하는 함수, reverse=True/False)

 

딕셔너리의 value값으로 정렬할 때는, '정렬할_자료'로 'dict.items()'를 지정하면 되고, key로는 'lambda x: x[1]'이라고 하면 됩니다.

 

dict.items()가 (key, value)의 쌍을 리턴고, 이 값들 중에서 두 번째 값인 value를 key로해서 정렬할 것이기에 'x=(key, value)' 중에서 두번째를 나타내는 'x[1]'이 리턴되게 하는 함수가 'lambda x: x[1]' 함수입니다.

 

lambda 함수가 좀 낯설 수 있는데, 수학 함수를 한 줄로 표현하는 파이썬 기능으로, 'lambda <입력값>: <입력값에 대한 함수식>' 형태를 가집니다. 위에서는 x라는 입력값에 대해서 x[1]을 리턴하는 함수로, 입력값이 dict.items()에 의한 (key, value)이기에, x = (key, value)가 되어, x[1]=value 가 리턴되게 됩니다. 

 

sorted 함수에 의해 리턴되는 값은 [(학생이름, 평균), (학생이름, 평균), ...]과 같은 형태가 되기에, 학생 이름만으로 리스트를 만들기 위해 '학생순위 = [k[0] for k in 평균정렬]'와 같은 코드가 사용되었습니다.

 

 -끝-

 


다음글: 04-3 튜플(tuple)

목차로 이동: [목차]CxO를 위한 코딩 강좌(파이썬을 중심으로)

반응형

'Programming > CxO를 위한 코딩' 카테고리의 다른 글

04-4 집합(set)  (0) 2020.06.25
04-3 튜플(tuple)  (0) 2020.06.25
04-1 리스트(list)  (0) 2020.06.25
04장. 데이터 다루기  (0) 2020.06.25
03-3 if 구문 익히기  (0) 2020.06.25