트랙
/
Python
Python
/
연습 문제
/
재고 관리
재고 관리

재고 관리

학습 연습 문제

소개

Python의 딕셔너리(dict)는 해시 가능한 _키_를 _값_에 연결하는 자료 구조예요. 다른 프로그래밍 언어에서는 크기를 조절할 수 있는 해시 테이블, 해시맵, 또는 연관 배열로 알려져 있죠. 딕셔너리는 Python에 내장된 유일한 매핑 타입이에요.

Keys는 해시 가능해야 하고 딕셔너리 전체에서 유일해야 해요. 키의 타입으로는 numbers, str, 또는 (불변 값들로 이루어진) tuples가 올 수 있어요. lists, dicts, sets처럼 가변 자료 구조는 키가 될 수 없어요. Python 3.7부터는 dict의 키 순서가 항목을 삽입한 순서대로 보장돼요.

values는 어떤 자료형이나 구조든 될 수 있어요. 값은 얼마든지 중첩될 수 있어서, 배열의 배열, 하위 딕셔너리, 그 밖의 사용자 정의 또는 복합 자료 구조를 담을 수도 있어요.

key가 주어지면 딕셔너리는 (평균적으로) 상수 시간에 value를 가져올 수 있어요(항목 수와는 무관해요). index 위치를 모른 채 list나 array 안에서 값을 찾는 것과 비교하면, dict는 메모리를 훨씬 많이 쓰지만 값을 아주 빠르게 가져와요. 딕셔너리는 항목이 많고 자주 접근하고 갱신해야 하는 상황에서 특히 유용해요.

딕셔너리 만들기

딕셔너리는 여러 방법으로 만들 수 있어요. 가장 간단한 두 가지는 dict()생성자를 사용하는 것과 dict _리터럴_을 선언하는 것이에요.

dict() 클래스 생성자

dict()(딕셔너리 클래스의 생성자)는 key, value 쌍으로 이루어진 이터러블이나 일련의 <name>=<value> _인자_와 함께 사용할 수 있어요:

#Passing a list of key,value tuples.
>>> wombat = dict([('name', 'Wombat'),('speed', 23),('land_animal', True)])
{'name': 'Wombat', 'speed': 23, 'land_animal': True}


#Using key=value arguments.
>>> bear = dict(name="Black Bear", speed=40, land_animal=True)
{'name': 'Black Bear', 'speed': 40, 'land_animal': True}

딕셔너리 리터럴

dict는 중괄호({})로 key : value 쌍을 감싼 _딕셔너리 리터럴_로 직접 입력할 수도 있어요:

>>> whale = {"name": "Blue Whale", "speed": 35, "land_animal": False}
{'name': 'Blue Whale', 'speed': 35, 'land_animal': False}

딕셔너리의 값에 접근하기

딕셔너리의 항목은 대괄호([]) 안에 _키_를 넣어 접근할 수 있어요. dict에 key가 없으면 KeyError가 발생해요:

>>> bear["speed"]
40

>>> bear["color"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'color'

.get(<key>, <default value>) 메서드로 항목에 접근하면 KeyError를 피할 수 있어요:

>>> bear.get("color", 'not found')
'not found'

딕셔너리 값 바꾸기와 추가하기

항목의 value는 _키_에 할당해서 바꿀 수 있어요:

#Assigning the value "Grizzly Bear" to the name key.
>>> bear["name"] = "Grizzly Bear"
{'name': 'Grizzly Bear', 'speed': 40, 'land_animal': True}

>>> whale["speed"] = 25
{'name': 'Blue Whale', 'speed': 25, 'land_animal': False}

새로운 key:value 쌍도 같은 방식으로 _추가_할 수 있어요:

# Adding a new "color" key with a new "tawney" value.
>>> bear["color"] = 'tawney'
{'name': 'Grizzly Bear', 'speed': 40, 'land_animal': True, 'color': 'tawney'}

>>> whale["blowholes"] = 1
{'name': 'Blue Whale', 'speed': 25, 'land_animal': False, 'blowholes': 1}

딕셔너리 항목 제거하기 (Pop)

.pop(<key>) 메서드로 딕셔너리 항목을 삭제할 수 있어요. .pop()은 (key, value) 쌍을 제거하고 그 value를 반환해요. .get()과 마찬가지로 .pop(<key>)는 두 번째 인자(dict.pop(<key>, <default value>))를 받을 수 있는데, 이 값은 key를 찾지 못했을 때 반환돼요. 이렇게 하면 KeyError가 발생하지 않아요:

#Using .pop() removes both the key and value, returning the value.
>>> bear.pop("name")
'Grizzly Bear'


#The "name" key is now removed from the dictionary.
#Attempting .pop() a second time will throw a KeyError.
>>> bear.pop("name")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'name'


#Using a default argument with .pop() will prevent a KeyError from a missing key.
>>> bear.pop("name", "Unknown")
'Unknown'

딕셔너리 순회하기(반복하기)

for item in dict나 while item으로 딕셔너리를 순회하면 기본적으로 _키_만 반복해요. 같은 루프 안에서 _대괄호_를 사용하면 _값_에도 접근할 수 있어요:

>>> for key in bear:
>>>     print((key, bear[key])) #this forms a tuple of (key, value) and prints it.
('name', 'Black Bear')
('speed', 40)
('land_animal', True)

.items() 메서드를 쓸 수도 있는데, 이 메서드는 (key, value) 튜플을 자동으로 반환해요:

#dict.items() forms (key, value tuples) that can be unpacked and iterated over.
>>> for key, value in whale.items():
>>>     print(key, ":", value)
name : Blue Whale
speed : 25
land_animal : False
blowholes : 1

마찬가지로 .keys() 메서드는 keys를 반환하고 .values() 메서드는 values를 반환해요.

지침

이 연습 문제에서는 재고 시스템을 관리해요.

재고는 항목 이름을 기준으로 정리하고, 사용 가능한 항목의 개수를 추적해야 해요.

재고에 항목을 추가하는 것도 처리해야 해요. 주어진 배열에 항목이 나타날 때마다, 재고에서 해당 항목의 수량을 1만큼 늘려요. 요청이 있으면 수량을 1만큼 줄여서 재고에서 항목을 삭제하는 것도 처리해야 해요.

마지막으로, 주어진 재고의 모든 키-값 쌍을 tuples로 이루어진 list로 반환하는 함수를 구현해야 해요.

1. 배열을 바탕으로 재고 만들기

create_inventory(<input list>) 함수를 구현해서 항목들의 입력 배열로부터 "재고"를 만들어요. 각 항목 이름과 그에 해당하는 수량을 짝지은 dict를 반환해야 해요.

>>> create_inventory(["coal", "wood", "wood", "diamond", "diamond", "diamond"])
{"coal":1, "wood":2, "diamond":3}

2. 기존 딕셔너리에 배열의 항목 추가하기

add_items(<inventory dict>, <item list>) 함수를 구현해서, 전달받은 재고에 항목 배열을 추가해요:

>>> add_items({"coal":1}, ["wood", "iron", "coal", "wood"])
{"coal":2, "wood":2, "iron":1}

3. 재고에서 항목 수량 줄이기

decrement_items(<inventory dict>, <items list>) 함수를 구현해요. 이 함수는 항목들의 list를 받아요. list에 항목이 나타날 때마다, 그 항목의 개수에서 1을 빼요:

>>> decrement_items({"coal":3, "diamond":1, "iron":5}, ["diamond", "coal", "iron", "iron"])
{"coal":2, "diamond":0, "iron":3}

재고의 항목 개수는 0 아래로 내려가면 안 돼요. 입력 list에 항목이 나타난 횟수가 남은 개수보다 많으면, 그 항목의 수량은 0으로 유지돼요. 개수가 0으로 떨어지면, 그 뒤의 차감 요청은 무시해요.

>>> decrement_items({"coal":2, "wood":1, "diamond":2}, ["coal", "coal", "wood", "wood", "diamond"])
{"coal":0, "wood":0, "diamond":1}

4. 재고에서 항목 완전히 삭제하기

remove_item(<inventory dict>, <item>) 함수를 구현해서, 재고에서 항목과 그 개수를 완전히 삭제해요:

>>> remove_item({"coal":2, "wood":1, "diamond":2}, "coal")
{"wood":1, "diamond":2}

재고에서 항목을 찾지 못하면, 함수는 원래 재고를 그대로 반환해야 해요.

>>> remove_item({"coal":2, "wood":1, "diamond":2}, "gold")
{"coal":2, "wood":1, "diamond":2}

5. 재고의 전체 내용 반환하기

list_inventory(<inventory dict>) 함수를 구현해요. 이 함수는 재고를 받아서 (item, quantity) 튜플들로 이루어진 배열을 반환해요. 이 배열에는 사용 가능한 항목(수량이 0보다 큰 항목)만 포함해야 해요:

>>> list_inventory({"coal":7, "wood":11, "diamond":2, "iron":7, "silver":0})
[('coal', 7), ('diamond', 2), ('iron', 7), ('wood', 11)]
GitHub에서 편집 링크가 새 창이나 탭에서 열려요
Python Exercism

재고 관리 문제를 시작해 볼 준비가 됐나요?

Exercism에 가입하고 Python 트랙을 개념 17개연습 문제 146개, 그리고 실제 사람의 멘토링과 함께 배우고 익혀 보세요. 모두 무료예요.