이전 장에서는 리스트와 튜플이라는 자료형에 대해 알아보았다.
이번에는 키를 이용해서 값을 추출할 수 있는 자료형인 "딕셔너리 dictionary" 에 대해서 알아보자.
주로 데이터베이스에서 흔히 볼 수 있는 구조인데,
딕셔너리는 값 value 과 관련된 키 key 가 있다는 것이 큰 특징이다.
딕셔너리를 만들 때는 중괄호 {} 를 사용한다.
간단하게 전화번호부를 만든다고 가정하고 딕셔너리에 대해 살펴보자.
phone_book = {} # 공백 딕셔너리를 생성
phone_book["홍길동"] = "010-1234-5678"
print(phone_book) # {'홍길동': '010-1234-5678'}
위의 코드를 보면 {} 를 이용하여 공백 딕셔너리를 만든다.
이름을 key 로 사용하고 value 에는 그 사람의 전화번호를 입력한다.
그러고 나서 딕셔너리를 출력해보면, 중괄호로 감싸져서 키와 값이 출력되는 것을 볼 수 있다.
위와 동일한 방식으로 딕셔너리에 여러 사람들의 전화번호를 추가할 수도 있다.
phone_book = {} # 공백 딕셔너리를 생성
phone_book["홍길동"] = "010-1234-5678"
phone_book["강감찬"] = "010-1234-6789"
phone_book["이순신"] = "010-1234-4567"
print(phone_book)
# {'홍길동': '010-1234-5678', '강감찬': '010-1234-6789', '이순신': '010-1234-4567'}
딕셔너리에서 가장 중요한 연산은 바로 "키를 가지고 연관된 값을 찾는 것"이다.
이는 다음과 같은 코드로 가능하다.
print(phone_book["강감찬"])
# 010-1234-6789
리스트에서는 인덱스를 가지고 항목을 찾을 수 있지만, 딕셔너리는 키를 가지고 값을 찾는다는 것이 다르다.
딕셔너리에서 사용되는 모든 키를 출력하려면 keys() 메소드를 사용하고,
모든 값을 출력하려면 values() 메소드를 사용한다.
print(phone_book.keys())
# dict_keys(['홍길동', '강감찬', '이순신'])
print(phone_book.values())
# dict_values(['010-1234-5678', '010-1234-6789', '010-1234-4567'])
그리고 딕셔너리 내부의 모든 값을 출력하려면 items() 라는 메소드를 사용하면 된다.
items() 메소드를 사용하면 (key, value) 튜플 형태로 데이터가 반환되므로 아래와 같이 활용할 수도 있다.
for name, phone_num in phone_book.items():
print(name, ':', phone_num)
# 홍길동 : 010-1234-5678
# 강감찬 : 010-1234-6789
# 이순신 : 010-1234-4567
앞선 장에서는 리스트의 여러 메소드들을 살펴보았는데, 이번에는 딕셔너리 자료형의 메소드들을 살펴보자.
메소드 | 하는 일 |
keys() | 딕셔너리 내의 모든 키를 반환한다. |
values() | 딕셔너리 내의 모든 값을 반환한다. |
items() | 딕셔너리 내의 모든 항목을 [키] : [값] 쌍으로 반환한다. |
get(key) | 키에 대한 값을 반환, 키가 없으면 None 을 반환한다. |
pop(key) | 키에 대한 값을 반환, 그 항목을 삭제한다. 키가 없으면 KeyError 예외 발생. |
popitem() | 제일 마지막에 입력된 항목을 반환하고, 그 항목을 삭제한다. |
clear() | 딕셔너리 내의 모든 항목을 삭제한다. |
이번에는 람다 함수에 대해서 살펴보자.
람다 함수란 "이름이 없는 함수"이다.
함수에 대해서 잘 모르겠다면 아래 게시글을 참고하자.
람다 함수는 간단한 1회용 작업에 유용하다.
필요한 기능을 함수로 정의해 두면, 필요할 때마다 호출해서 사용하는 것이 편리한데
가끔씩은 함수를 만들지 않고 함수하된 기능만을 불러 사용하고자 할 경우가 있다.
이럴 때는 람다 함수를 이용하면 된다.
람다 함수는 이름이 없기 때문에 재사용이 불가능하다고 생각할 수 있는데 그건 아니다.
이름이 필요할 경우에는 표현식에 할당문을 사용하여 재사용할 수 있다.
람다 함수를 사용할 때 주의할 점은 표현식 안에서 새로운 변수를 선언할 수 없다는 것이다.
그리고 람다 함수의 반환 값은 변수 없이 식 한 줄로 표현할 수 있어야 하기 때문에,
복잡한 기능의 함수는 def 로 정의하여 쓰는 것이 좋다.
두 수를 입력받아 두 수의 합을 반환하는 람다 함수를 만들어보자.
일반 함수는 다음과 같이 정의할 수 있을 것이다.
def add(x, y):
return x + y
이에 비해 람다 함수는 다음과 같이 쓸 수 있다.
lambda x,y : x + y
이 람다 함수를 이용해서 바로 두 수의 합을 출력해보자.
print('100과 200의 합은 :', (lambda x,y : x + y)(100, 200))
# 300
람다 함수를 이용해서 특정 튜플에서 첫 항목만을 추출하는 함수를 정의할 수 있다.
코드는 다음과 같다.
t = (100, 200, 300)
print((lambda x: x[0])(t))
# 100
그렇다면 이번엔 딕셔너리를 이용해 간단한 예제 코드를 만들어보자.
편의점 재고 관리를 수행하는 프로그램을 작성할텐데,
이를 위해 편의점에서 판매하는 물건의 재고를 딕셔너리에 저장한다.
그리고 사용자로부터 물건의 이름을 입력받아서 물건의 재고를 출력하는 프로그램을 작성해보자.
초보자의 입장에서 간단하게 문제를 해결해야 하기 때문에 아주 작은 편의점이라고 가정해보자 :)
취급하는 물건은 다음과 같다.
items = { "커피음료": 7, "펜": 3, "종이컵": 2, "우유": 1, "콜라": 4, "책": 5 }
input() 문을 사용하여 물건의 이름을 사용자로부터 입력받고, items[물건의 이름] 을 통해서
물건의 재고를 조회하고 출력하면 된다.
결과는 다음과 같이 나와야 한다.
먼저 해답 코드를 보지 말고 코딩해보자.
해답 코드는 생각보다 간다하다. 다음 코드를 보자.
items = { "커피음료": 7, "펜": 3, "종이컵": 2, "우유": 1, "콜라": 4, "책": 5 }
name = input("물건의 이름을 입력하시오: ")
print('재고 :', items[name])
그렇다면 이번엔 영한 사전을 만들어보자.
문제를 많이 겪어보며 프로그램을 짜볼수록 실력은 늘게 된다.
문제는 다음과 같다.
영한 사전과 같이 영어 단어를 주면, 이에 해당하는 우리말 단어를 알 수 있게 하려고 한다.
딕셔너리 구조를 활용하여 단어를 입력하고, 검색할 수 있는 프로그램을 만들어보자.
실행된 결과는 명령 프롬프트 '$' 가 나타나고, 입력 명령은 '<', 검색 명령은 '>' 로 표현하자.
입력은 "영어 단어 : 우리말 단어" 형태로 이루어지며, 검색은 영어 단어를 입력한다.
프로그램의 종료는 'q' 키를 입력하자.
물론 지금까지 공부한 것을 바탕으로 프로그램을 짜기엔 조금 힘들 수 있다.
계속해서 배워나갈 내용들이 포함되어 있지만, 고민해보는 시간만큼 성장할 것이다.
다음은 vscode 를 이용해 해당 프로그램을 실행한 화면이다.
힌트가 있다면, while True : 를 이용해 무한루프를 돌리고, 사용자가 'q' 를 입력할 때까지 반복시킨다.
입력 받은 시작 문자가 < 이면 입력문 s 를 받아 s.split(':') 를 통해서 입력문자를 구분할 수 있다.
사용자의 입력을 받으면 단어의 앞이나 뒤에 의미 없는 공백 문자가 입력될 수도 있다.
strip() 함수는 입력 문자열의 앞 뒤에 있는 공백을 깨끗하게 정리해준다.
입력된 문자열을 키:값 구조의 딕셔너리에 넣어서 > 가 입력될 때
이 값을 키로 하여 조회하도록 하자.
문자열을 다루는 함수들은 처음 보는 것이기 때문에 생소할 수 있다.
이 부분은 아래 게시글을 참고하면 된다.
그러면 이제 해답 코드를 보자.
이때까지의 프로그램들보다 해결하기 어려웠을 수도 있고, 해결을 하지 못 했을 수도 있다.
하지만 괜찮다. 해결하는 것이 중요하지 않다.
고민하는 시간이 중요하다.
print("사전 프로그램 시작... 종료는 q를 입력")
dictionary = {}
while True:
st = input('$ ')
command = st[0] # 첫 입력 문자를 추출한다
if command == '<':
st = st[1:]
inputStr = st.split(':')
if len(inputStr) < 2 :
print('입력 오류가 발생했습니다.')
else:
dictionary[inputStr[0].strip()] = inputStr[1].strip()
elif command == '>':
st = st[1:]
inputStr = st.strip()
if inputStr in dictionary:
print(dictionary[inputStr])
else :
print('{}가 사전에 없습니다.'.format(inputStr))
elif command == 'q':
break
else :
print('입력 오류가 발생했습니다.')
print("사전 프로그램을 종료합니다.")
앞에서 배웠던 반복문, 조건문, 리스트, 슬라이싱, 딕셔너리 등
다양한 개념들이 동시에 사용된다.
정답이 꼭 이 코드와 똑같지 않을 수 있다. 코드를 비교해보며 어떻게 코드를 짜는 것이
가장 좋을 지 고민해보는 시간이 중요하다.
이번 장에서는 딕셔너리에 대해서 알아보았다. 뿐만 아니라 조금 어려운 문제를 도전하면서
프로그래밍적인 사고를 키워보기도 했다.
프로그래밍을 처음 공부하는 입장에선 부담스러울 수 있지만,
앞으로 더 공부를 하고 파이썬을 이용해 데이터과학과 머신러닝을 접하게 된다면 훨씬 어려워질 것이다.
그렇기 때문에 작은 문제를 해결하는 것부터 연습하며 기초를 다져야 한다는 것을 느꼈다.
다양한 예제들을 접해보며 실력을 키워나가자 :)
출처 : 따라하며 배우는 파이썬과 데이터 과학 - 천인국, 박동규, 강영민