複数の変数を値に対してテストする方法

python if-statement comparison match boolean-logic


複数の変数を整数と比較して3文字の文字列を出力する関数を作ろうとしています。これをPythonに変換する方法はないかと思っていました。と言うことで。

x = 0
y = 1
z = 3
mylist = []

if x or y or z == 0 :
    mylist.append("c")
if x or y or z == 1 :
    mylist.append("d")
if x or y or z == 2 :
    mylist.append("e")
if x or y or z == 3 : 
    mylist.append("f")

のリストを返します。

["c", "d", "f"]

このようなことは可能なのでしょうか?





Answer 1 Martijn Pieters


あなたはブーリアン式がどのように機能するかを誤解しています。あなたが探しているのは

if x == 1 or y == 1 or z == 1:

それ以外の場合、 xy は独自に評価されます( 0 の場合は False 、それ以外の場合は True )。

あなたはタプルに対する包含テストを使用してそれを短くすることができます:

if 1 in (x, y, z):

というか、もっといいかもしれません。

if 1 in {x, y, z}:

set を使用して 、一定コストのメンバーシップテストを利用 in ます( inには、左側のオペランドが何であれ、一定の時間がかかります)。

or を使用すると 、Pythonは演算子の両側を別々の式として認識ます。 式 x or y == 1 は最初に x のブールテストとして扱われ、それがFalseの場合、式 y == 1 がテストされます。

これは、 演算子の優先順位によるものです。 or 演算子は == テストよりも優先順位が低いため、後者が最初に評価されます。

ただし、これが当てはまらず 、式 x or y or z == 1 が実際には (x or y or z) == 1 として解釈されたとしても、期待どおりには動作しません。

x or y or z は、「真」である最初の引数に評価されます。たとえば、 False 、数値0または空ではありません(ブールコンテキストでPythonがfalseと見なすものの詳細については、 ブール式を参照してください)。

したがって、値 x = 2; y = 1; z = 0 y = 1; z = 0 、 x or y or z2 に解決されます。これは、それが引数の最初の真のような値だからです。 y == 1True であっても、 2 == 1False になります 。

同じことが逆にも当てはまります。 単一の変数に対して複数の値をテストします。 x == 1 or 2 or 3 は、同じ理由で失敗します。 x in {1, 2, 3} x == 1 or x == 2 or x == 3 またはxを使用します。




Answer 2 dansalmo


あなたの問題は、次のような辞書構造を使えば、より簡単に解決できます。

x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]



Answer 3 ThatGuyRussell


Martijn Pieters が述べているように、正しい、そして最速のフォーマットは以下の通りです。

if 1 in {x, y, z}:

彼のアドバイスを使用すると、前のステートメントが True であるか False であるかに関係なく、Pythonが各ステートメントを読み取るように、個別のifステートメントを持つことになります。 といった:

if 0 in {x, y, z}:
    mylist.append("c")
if 1 in {x, y, z}:
    mylist.append("d")
if 2 in {x, y, z}:
    mylist.append("e")
...

これは機能しますが、辞書を使い慣れている場合は(ここで何をしたかを参照)、最初の辞書で数字と必要な文字をマッピングし、forループを使用するだけでこれをクリーンアップできます。

num_to_letters = {0: "c", 1: "d", 2: "e", 3: "f"}
for number in num_to_letters:
    if number in {x, y, z}:
        mylist.append(num_to_letters[number])



Answer 4 akaRem


x or y or z == 0 直接書き込む方法は、

if any(map((lambda value: value == 0), (x,y,z))):
    pass # write your logic.

しかし、私はあなたがそれを好きだとは思いません。)そして、この方法は醜いです。

もう一つの方法(ベター)は

0 in (x, y, z)

ところで if sはこのようなものとして書くことができます

my_cases = {
    0: Mylist.append("c"),
    1: Mylist.append("d")
    # ..
}

for key in my_cases:
    if key in (x,y,z):
        my_cases[key]()
        break



Answer 5 ytpillai


もしあなたが非常に怠け者であれば、値を配列の中に入れることができます。例えば

list = []
list.append(x)
list.append(y)
list.append(z)
nums = [add numbers here]
letters = [add corresponding letters here]
for index in range(len(nums)):
    for obj in list:
        if obj == num[index]:
            MyList.append(letters[index])
            break

数字や文字を辞書に入れて実行することもできますが、これは単純なif文よりもLOT以上に複雑です。それは、あなたが余分な怠け者になろうとしているために得られるものです :)

もう一つ、あなたの

if x or y or z == 0:

はコンパイルされますが、あなたが望む方法ではありません。if 文の中に変数を入れただけの場合 (例)

if b

は変数がNULLでないかどうかをチェックします。上記の文を書くもう一つの方法は、次のようになります。

if bool(b)

Bool は python に組み込まれた関数で、基本的には boolean 文を検証するコマンドを実行します (それが何かわからない場合は、今あなたが if 文の中で作ろうとしているものです :)

私が見つけたもう一つの怠惰な方法は次のとおりです。

if any([x==0, y==0, z==0])