一覧PG-08-2 · コレクションの操作

辞書と集合の基本操作

商品の登録情報を検索・更新し、欠落の扱いを確認します。最後に依頼された商品と取扱商品の集合を照合し、共通部分と未取扱いの種類を求めます。

説明

辞書はキーから値を取得し、集合は要素が含まれるかを調べます。登録済みの0やNone、存在しないキー、重複する値について、それぞれの扱いを確認します。

商品の登録情報を検索・更新し、欠落の扱いを確認します。最後に依頼された商品と取扱商品の集合を照合し、共通部分と未取扱いの種類を求めます。

1キーと値を用意

penは在庫0、bookは在庫数未確認のNoneとして登録します。別の辞書では整数キー0と文字列キー"0"も比較します。

stock = {"pen": 0, "book": None}登録済みの0と未確認値; labels = {0: "numeric", "0": "text"}異なる型のキー; print(stock["pen"], labels[0], labels["0"])キーから値を取得

辞書の整数キー0は「先頭の位置」という意味ではなく、キーそのものです。文字列キー"0"とは別の対応になります。

2getだけでは欠落とNoneが同じに見える

bookと未登録のmugについて、getの結果とキーの存在を並べます。

print(stock.get("book"), stock.get("mug")既定値なしの検索); print("book" in stock, "mug" in stockキーの存在を確認); print(stock)読取り後の辞書

どちらのgetもNoneですが、bookは登録済み、mugは未登録です。getで読み取っただけではmugのキーは追加されません。

3必須キーの取得では欠落が例外になる

未登録のmugを添字で読みます。

stock["mug"]必須としてキーを取得

KeyErrorになります。キーが必ずあるべき処理なら欠落をエラーとして検出できます。getで既定値を返すかどうかは、欠落を許す仕様かに合わせて選びます。

4既定値の取得と追加

まずgetで0を返し、次にsetdefaultで未登録時の値0を追加します。

print(stock.get("mug", 0), "mug" in stock値を返すだけ); print(stock.setdefault("mug", 0), "mug" in stock未登録時に追加); print(stock)変更後の辞書

getの後は未登録のまま、setdefaultの後はmug: 0が追加されています。setdefaultは既存キーの値を指定値で上書きする操作ではありません。

5既存キーを更新する

penの入庫を反映し、同じキーが重複したデータから辞書を作る場合も確認します。

stock["pen"] = 3同じキーの値を更新; updates = [("pen", 1), ("pen", 5)]重複キーを含む入力; print(stock)更新後; print(dict(updates))後の値が残る辞書化

stockのpenは3へ更新され、キーは増えません。重複するpenから辞書を作ると、後の5が残ります。辞書化は重複をエラーにする検査ではないので、重複を禁止するなら別途検出します。

6集合にすると回数が失われる

依頼列にpenが二回含まれています。集合へ変換して表示します。

requests = ["pen", "mug", "pen", "book"]重複を含む依頼列; requested = set(requests)種類の集合; print(len(requests), len(requested), sorted(requested))件数と種類数

4件の依頼が3種類へまとまります。集合は出現回数と元の順序を保持するための型ではありません。表示を毎回比較しやすくするためsortedで順序を固定しています。

7共通部分と不足分

取扱いのある種類をpen・mug・bagとします。依頼との共通部分、未取扱いの種類、依頼されていない種類を求めます。

available = {"pen", "mug", "bag"}取扱いのある種類; print(sorted(requested & available共通部分)); print(sorted(requested - available依頼のうち未取扱いの種類)); print(sorted(available - requested依頼されていない種類))

共通はmugとpen、未取扱いはbook、依頼外はbagです。差集合は引く向きで結果が変わります。これは取扱い種類の照合であり、現在の在庫が0のmugも含みます。依頼個数分の在庫が足りるかは別に検査します。

8依頼の全種類を取り扱っているか

集合の包含で依頼の全種類を扱っているか調べ、bookを取扱いへ追加して再判定します。

print(requested <= available)依頼の全種類を扱うか; available.add("book")bookを取扱いへ追加; print(requested <= available, sorted(requested | available))包含と和集合

最初はFalse、追加後はTrueです。和集合は両方に含まれる種類を一つずつ並べます。辞書の対応情報やリストの件数が必要な場面では、それらを集合へ置き換えすぎないようにします。

まとめ

辞書の欠落と、登録済みの0・Noneを分けて扱います。

集合は種類の照合に使い、出現回数や数量の情報は別に保持します。

操作履歴と解説を振り返れます。

Python 3

1
stock = {"pen": 0, "book": None}; labels = {0: "numeric", "0": "text"}; print(stock["pen"], labels[0], labels["0"])
0 numeric text
2
print(stock.get("book"), stock.get("mug")); print("book" in stock, "mug" in stock); print(stock)
None None
True False
{'pen': 0, 'book': None}
3
stock["mug"]
Traceback (most recent call last):
  File "<console>", line 1, in <module>
KeyError: 'mug'
4
print(stock.get("mug", 0), "mug" in stock); print(stock.setdefault("mug", 0), "mug" in stock); print(stock)
0 False
0 True
{'pen': 0, 'book': None, 'mug': 0}
5
stock["pen"] = 3; updates = [("pen", 1), ("pen", 5)]; print(stock); print(dict(updates))
{'pen': 3, 'book': None, 'mug': 0}
{'pen': 5}
6
requests = ["pen", "mug", "pen", "book"]; requested = set(requests); print(len(requests), len(requested), sorted(requested))
4 3 ['book', 'mug', 'pen']
7
available = {"pen", "mug", "bag"}; print(sorted(requested & available)); print(sorted(requested - available)); print(sorted(available - requested))
['mug', 'pen']
['book']
['bag']
8
print(requested <= available); available.add("book"); print(requested <= available, sorted(requested | available))
False
True ['bag', 'book', 'mug', 'pen']

演習完了