answer9_3_2.py

menu = {
  "カツ丼": "乳 卵 小麦",
  "天そば": "卵 小麦 そば えび",
  "かに玉": "卵 小麦 かに",
  "鶏ピー": "小麦 落花生",
}

choice = input("メニューを選んで下さい:")
allergen = set()
for dish in choice.split():
    allergen |= set(menu[dish].split())
# ここまででalergenに、選んだメニューに含まれる
# すべてのアレルギー物質の集合がセットされている

allergic = set(input("アレルギーは?").split())
# メニューに含まれるもの(allergen)と入力されたもの(allergic)に
# 共通するアレルギー物質を積集合として求める
contained = allergen & allergic
if contained:  # 共通するものが1つでもあれば
  algn_list = "、".join(list(contained))
  print(f"次のものが含まれています:{algn_list}")
else:
  print(f"問題ありません")

# 章末問題 9章【3】(2)解答例
#
# 11行目までは(1)の解答例と同じです。
#
# 15行目で、入力された文字列を空白文字で切ったものを
# setコンストラクタに渡して、問題となるアレルギー物質の
# 集合を得ています。18行目は積集合の演算で、
# 選んだメニューに入っているアレルギー物質と、
# 入力されたアレルギー物質の共通要素を得ています。
#
# 19行目で if contained: としていますが、集合型も
# 文字列やリストと同様、空なら偽、そうでないなら真を意味します。
# そのため、入力したアレルギー物質が含まれていればそれらが出力され、
# 含まれていなければ「問題ありません」と表示されます。
#
# 19行目は if contained != set(): と書いて空集合と比較しても、
# また if len(contained) > 0: と書いて要素数を用いて判断しても、
# 同様に動きます。