質問するログイン新規登録
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

348閲覧

Python リスト内包表記 all関数

rin_23

総合スコア4

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2023/10/22 15:08

編集2023/10/22 15:36

0

0

実現したいこと

今Pythonでリストについて学んでいるのですが、リスト内包表記の使い方がいまいち分からなくて、困っています。
以下のようなプログラミングを今作っています。

三つの原料でどの飲み物ができるかを出力するプログラミングです。

  • 最後の2つの引数は飲み物のリストと原料のタプルのリスト
  • 戻り値は、指定された3つの原料で作ることができる飲み物の名前
  • 一致する飲み物が見つからない場合、関数は None を返す
  • 3つ以上の原料を含む飲み物を作ることは可能だが、原料は3つしか提供されない

Expected output

python

1>>> find_drink("cachaca", "sugar", "lime", drinks, ingredients) 2"caipirinha" 3 4>>> find_drink("ice", "olives", "vodka", drinks, ingredients) 5"vodka martini" 6>>> find_drink("ice", "olives", "vermouth", drinks, ingredients) 7"vodka martini" 8 9>>> find_drink("white rum", "gin", "ice", drinks, ingredients) 10None 11

試したこと

all関数を使ってプログラミングを書かないといけないのですが、リスト内包表記とall関数の使い方がいまいち理解できず、これであっているのかもよくわかりません。
drinkname = [x for x in ingredients if all(w in x for w in list)] これは、インターネットで同じような書き方があったので少し変えていろいろ試してみましたが、どういう意味か理解できていません。

python

1def find_drink(ingredient1, ingredient2, ingredient3, drinks, ingredients): 2 for DRINK, INGREDIENTS in zip(drinks, ingredients): 3 list = [ingredient1, ingredient2, ingredient3] 4 drinkname = [x for x in ingredients if all(w in x for w in list)] 5 i = ingredients.index(drinkname) 6 return drinks[i] 7 8drinks = ["caipirinha", "mojito", "gin tonic", "vodka martini"] 9 10ingredients = [ 11 ("cachaca", "sugar", "lime"), 12 ("white rum", "sugar cane juice", "lime juice", "soda water", "mint"), 13 ("gin", "tonic water", "ice"), 14 ("vodka", "vermouth", "ice", "olives"), 15] 16 17print(find_drink("cachaca", "sugar", "lime", drinks, ingredients)) 18print(find_drink("ice", "olives", "vodka", drinks, ingredients)) 19print(find_drink("ice", "olives", "vermouth", drinks, ingredients)) 20print(find_drink("white rum", "gin", "ice", drinks, ingredients))

i = ingredients.index(drinkname)とreturn drinks[i]は間違っているのは分かっていますが、一応試したこととして書きました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meg_

2023/10/22 15:23

> all関数を使ってプログラミングを書かないといけないのですが、リスト内包表記とall関数の使い方がいまいち理解できず、これであっているのかもよくわかりません。 リスト内包表記の使用も必須なのでしょうか?
rin_23

2023/10/22 15:35

必須ではないのですが、できればall()とリスト内包表記を組み合わせて使用し、原料が合っているかチェックしたいです。
guest

回答2

0

ベストアンサー

質問のコードに試行錯誤の後が見えますが、同様のやりかたで進めてみます。
※ 一部変数名は変えています。

まずは、通常のやりかたで書いてみます。

python

1def find_drink(ingredient1, ingredient2, ingredient3, drinks, ingredients): 2 for drink, ingredients in zip(drink_list, ingredients_list): 3 if ingredient1 in ingredients and \ 4 ingredient2 in ingredients and \ 5 ingredient3 in ingredients: 6 return drink 7 else: 8 return None

全てのレシピ(zip(drink_list, ingredients_list))について引数の材料を全て含むものがあれば返すようにしています。
ここでは「全ての」をandで表現していますが、ここをall()に書き換えましょう。

python

1def find_drink(ingredient1, ingredient2, ingredient3, drinks, ingredients): 2 for drink, ingredients in zip(drink_list, ingredients_list): 3 4 if all((ingredient1 in ingredients, 5 ingredient2 in ingredients, 6 ingredient3 in ingredients)): 7 return drink 8 else: 9 return None

andを使ったときとall()を使ったときで同じ判定(ingredient? in ingredients)を使っています。

次はこのall()に入っている引数をタプル内包表記に書き換えます。(ingredient? in ingredients)のところがくりかえされているがキーです。

python

1def find_drink(ingredient1, ingredient2, ingredient3, drinks, ingredients): 2 for drink, ingredients in zip(drink_list, ingredients_list): 3 4 contents = [ingredient1, ingredient2, ingredient3] 5 if all(ingredientx in ingredients for ingredientx in contents): 6 return drink 7 else: 8 return None

慣れないとわかりにくいかもしれませんが、 all()の引数にはingredientx in ingredientsのingredientlxをingredient1~3に置き換えたものを入れたいわけなのでこのような記述になります。

最後に、外側のfor分をリスト内包表記に書き換えます。

python

1def find_drink(ingredient1, ingredient2, ingredient3, drinks, ingredients): 2 contents = [ingredient1, ingredient2, ingredient3] 3 result_list = [drink for drink, ingredients in zip(drink_list, ingredients_list) if all(ingredientx in ingredients for ingredientx in contents)] 4 5 if result_list: 6 return result_list[0] 7 else: 8 return None

元のfor分は中でreturnしていますが、内包表記ではリターンするのではなく、結果のリストが作られます。
リストは条件にあてはまったものが入っています。空であればNoneを返します。中身が入っていれば、最初のものを返します。 候補が複数あったとしても、他のコードは最初のものを返しますから、これで同等です。

投稿2023/10/23 08:42

TakaiY

総合スコア14578

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

drinkname = [x for x in ingredients if all(w in x for w in list)]
で、drinknameに代入されるのは、「原料のタプル」ではなくて「原料のタプルのリスト」です。
例えば[("cachaca", "sugar", "lime")]
("cachaca", "sugar", "lime")[("cachaca", "sugar", "lime")]は異なる物であることは分かるでしょうか?

ingredients.index(drinkname)は、「原料のタプルのリスト」から「原料のタプル」を探す意図でしょうが、実際に探しているのは「原料のタプルのリスト」で、「原料のタプルのリスト」には「原料のタプルのリスト」は含まれていないので、常にエラーになるかと思います。

また、見つかったか見つからなかったのかの判断も必要です。

あと、今回質問の本筋では無いですが、変数名にlistを使うとlist関数が上書きされて使えなくなるので一般的には駄目です。

投稿2023/10/22 17:35

編集2023/10/23 02:30
otn

総合スコア86387

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.30%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問