トラック
/
Python
Python
/
演習
/
在庫管理
在庫管理

在庫管理

学習演習

はじめに

Pythonの辞書(dict)は、ハッシュ可能な_キー_を_値_に対応付けるデータ構造で、他のプログラミング言語ではサイズ変更可能なハッシュテーブル、ハッシュマップ、[連想配列][associative-array)として知られています。 辞書は、Pythonで唯一の組み込みマッピング型です。

Keysはハッシュ可能でなければならず、辞書全体で一意でなければなりません。 キーの型にはnumbers、str、tuples(_イミュータブル_な値)などがあります。 lists、dicts、setsのような_ミュータブル_なデータ構造を含めることはできません。 Python 3.7以降、dictのキーの順序は、エントリを挿入した順序になることが保証されています。

valuesはどのようなデータ型やデータ構造でもかまいません。 値は_いくらでも_入れ子にできるので、リストのリストやサブ辞書、その他のカスタムあるいは複合的なデータ構造を含めることもできます。

keyがわかっていれば、辞書はvalueを(平均して)一定の時間で取り出せます(エントリの数には依存しません)。 listやarrayの中から値を探す場合(indexの位置がわからない場合)と比べると、dictはメモリをかなり多く使いますが、取り出しは非常に高速です。 辞書は、要素の集まりが大きく、頻繁にアクセスして更新する必要がある場面で特に役立ちます。

辞書の作成

辞書はさまざまな方法で作成できます。 最もわかりやすいのは、dict()コンストラクターを使う方法と、dictの_リテラル_を宣言する方法の2つです。

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}

辞書の値にアクセスする

辞書のエントリには、角括弧([])に入れた_key_を使ってアクセスできます。 keyがdictに存在しない場合は、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は、その_key_に代入することで変更できます。

#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>)は2番目の引数(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を使って辞書をループすると、デフォルトでは_keys_だけが繰り返されます。 同じループの中で、_角括弧_を使えば_values_にもアクセスできます。

>>> 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. 在庫からアイテムを減らす

アイテムのlistを受け取るdecrement_items(<inventory dict>, <items 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. 在庫の内容をすべて返す

在庫を受け取り、(item, quantity)タプルの配列を返すlist_inventory(<inventory dict>)関数を実装します。この配列には、_利用可能_なアイテム(数量が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に登録すれば、17個のコンセプト146個の演習、そして本物の人間によるメンタリングとともに、Pythonを学んでマスターできます。すべて無料です。