質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

Q&A

解決済

6回答

849閲覧

python:条件文を表す記号の変数保持した時,条件式で使用する方法がわからない

kkm

総合スコア1

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Python

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

0グッド

0クリップ

投稿2022/07/23 07:13

前提

pythonでリストの中に存在する条件文を表す記号(例:'>', '<'など)をif文で使用したいと考えています.
そのとき,条件文を表す記号はどのように使用すればいいのでしょうか.
条件文を表す記号は,リストの中では文字として格納されています.

実現したいこと

・文字として,リストの中に入っている条件文の記号をif文で使用したい.
・特定の数字が条件に従っているかを確認したい.

発生している問題・エラーメッセージ

SyntaxError: invalid syntax

→構文エラーなので,pythonの構文に従っていないことによるエラーなのは,わかるのですが解決法がわからないです.

試したこと

例えば,35がそれぞれ30以上,40以下かを確かめたいと思います.
その時に,それぞれ指定の値「35」が条件を満たしたかを確認するプログラムが以下になります(実際は実行できない).
「if 35 a b:」が「if 35 > 30」「if 35 < 40」のイメージで条件文を記述したいです.
そもそも,条件文の記号のデータ型がなんなのかわかっていないです.(文字列なのか,数値なのか)

python

1l1 = ['>', '<'] 2l2 = [30, 40] 3 4for i, (a, b) in enumerate(zip(l1, l2)): 5 6for a, b in zip(l1, l2): 7 if 35 a b: #ここでエラー(条件文の記号は変数で表すことはできないからか??) 8 print(f'{i+1}回目', 'OK') 9 else: 10 print(f'{i+1}回目', 'NG')

今回の場合は,OUTPUTは,

1回目 OK 2回目 OK

となることを目指しています.

基本的な構文かもしれませんが解決できる方がいれば,よろしくお願いいたします.

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

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

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

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

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

guest

回答6

0

そんな難しく考えないで、単に、'<' なら n<b の結果を、'>' なら n>b の結果を返す関数を組めばよろしい

#自分のできる範囲でやっていけばいいかと

投稿2022/07/23 07:27

y_waiwai

総合スコア87774

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

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

melian

2022/07/23 07:58

回答を引用しました。ご了承下さい。
guest

0

普通の処理で解決するべきであってevalなどを安易に使ってはいけない
特に初心者にeval(やexec)のような方法を安易に教えてはいけない
と思っている人は多そうで、それが回答の評価にそのまま出ている気がします。

普通のプログラミングで解決できない人が、メタプログラミングをやろうとするのはよくないと思います。
"黒魔術"と呼称されるのは、そのような禁忌の意味も込められているかと。

こんな感じで十分かと。

python

1l1 = ['>', '<'] 2l2 = [30, 40] 3 4 5for i, (a, b) in enumerate(zip(l1, l2), start=1): 6 target = 35 7 8 if a == '<': 9 result = target < b 10 elif a == '>': 11 result = target > b 12 else: 13 raise RuntimeError 14 15 if result: 16 print(f'{i}回目', 'OK') 17 else: 18 print(f'{i}回目', 'NG')

operator.ltとoperator.gtあたりで

python

1from operator import gt, lt 2 3l1 = ['>', '<'] 4l2 = [30, 40] 5 6comp = {'>': gt, '<': lt} 7 8for i, (a, b) in enumerate(zip(l1, l2), start=1): 9 if comp[a](35, b): 10 print(f'{i}回目', 'OK') 11 else: 12 print(f'{i}回目', 'NG')

もいいかと。

投稿2022/07/23 08:21

編集2022/07/23 23:46
quickquip

総合スコア11038

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

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

quickquip

2022/07/23 08:22

どこにどうコメントするのがいいかわからなかったので回答にしました。
kkm

2022/07/24 14:58

もともとは,1から100の整数の中から,ヒントが与えられて,一意の値を特定するプログラムを作成するというものでした. INPUTとして条件式の記号と値が与えられて,OUTPUTとして一意の値を特定するというものです. INPUT:「> 30,< 40,/ 5」の場合は, OUTPUT:35が出力されるというプログラムが作成したかったです. 初めにリストとして,1から100の値を保持したリストを作成し,単純に入力された値や文字をリストや辞書として保持して,条件式の記号が「>」「<」「/」なのかを判定して, IF文を自分で作成して新しいリストを作成するだけでした. 組み込み関数もむやみに使用してはいけないこともわかりました,ありがとうございます. 他の方も色々と教えていただきありがとうございました.
guest

0

※ メソッドで。

python

1l1 = [int.__gt__, int.__lt__] 2l2 = [30, 40] 3 4for i, (a, b) in enumerate(zip(l1, l2)): 5 if a(35, b): 6 print(f'{i+1}回目', 'OK') 7 else: 8 print(f'{i+1}回目', 'NG')

追記
y_waiwai 氏曰く:

そんな難しく考えないで、単に、'<' なら n<b の結果を、'>' なら n>b の結果を返す関数を組めばよろしい

確かにその通りなので、

python

1l1 = [int.__gt__, int.__lt__]

python

1l1 = [lambda x, y: x > y, lambda x, y: x < y]

に変更してもよいかと。

投稿2022/07/23 07:19

編集2022/07/23 07:57
melian

総合スコア19805

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

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

0

ベストアンサー

(書いている途中に quickquip さんの回答が入りました。 基本同内容です。)
evalを使うように提示された回答がBAになっているのでコメントのつもりで書き込みます。

evalやexecなどのように、文字列をコードとして実行する仕組みは「プログラム実行中にプログラムを生成/変更することができる」機能ですので、とても強力です。
しかし、その分、プログラムに脆弱性を持ち込んでしまう危険性があり、場合によってはシステムを危険にさらすことにつながる可能性もあり、 よく考えて使うべきです。
今回の例でそのような危険はたぶん無い(言いきれるわけではないけど)と思うので、evalによる解決でもいいと思うのですが、evalを使わなくても実現できるという知識は持っておく必要があると思います。

そして、evalを使わなくても実現できることを、evalやexecを使って解決するのは悪手だと思います。
たぶん、evalを使わない回答を提案している回答者の方も同意見なのだと思いますし、そういう考えのかたは多いでしょう。

具体的にどのような危険があるのかと言えば、リストにある「'>'」などの文字列が、もし外部から提供されたものだった場合、その外部のシステムに悪意があれば、ここにシステムに悪影響のあるコマンドを入れることができるでしょう。それをチェックせずにevalを使って実施すれば、問題が発生するのはあきらかです。 Webでのスクリプトインジェクションと同じですね。

意見だけはだ何なので、こんなのもあるよという案を出してあきます。
l1に入っている文字列はそのままで、それに対応する関数をdictで持つ方法です。
この方法であれば、想定外の入力では動作しないようするのは簡単です。提示のコードだと落ちるし、チェックを入れることもできるでしょう。

python

1l1 = ['>', '<'] 2l2 = [30, 40] 3 4comp = {'>': (lambda a, b: a > b), 5 '<': (lambda a, b: a < b)} 6 7for i, (a, b) in enumerate(zip(l1, l2)): 8 if comp[a](35, b): 9 print(f'{i+1}回目', 'OK') 10 else: 11 print(f'{i+1}回目', 'NG')

投稿2022/07/23 09:05

TakaiY

総合スコア12765

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

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

0

この辺を使えば多分できますね。
https://techacademy.jp/magazine/40662

投稿2022/07/23 07:21

usekay

総合スコア395

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

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

0

evalを使うと文字列を評価できます。ご質問者様がイメージしていることができるかと思います

「if 35 a b:」が「if 35 > 30」「if 35 < 40」のイメージで条件文を記述したいです.

python

1l1 = ['>', '<'] 2l2 = [30, 40] 3 4for i, (a, b) in enumerate(zip(l1, l2)): 5 if eval(f"35 {a} {b}"): 6 print(f'{i+1}回目', 'OK') 7 else: 8 print(f'{i+1}回目', 'NG')

投稿2022/07/23 07:37

編集2022/07/23 07:39
East_san

総合スコア407

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問