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

683
user1877442 2013-02-28 02:26.

複数の変数を整数と比較し、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"]

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

24 answers

912
Martijn Pieters 2013-02-28 02:27.

ブール式がどのように機能するかを誤解しています。それらは英語の文のようには機能せず、ここですべての名前について同じ比較について話していると推測します。あなたは探している:

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

xそして、y(そうでない場合は、自分で評価されFalseている場合0Trueそうでありません)。

タプルに対する包含テストを使用して、これを短縮できます。

if 1 in (x, y, z):

またはそれ以上:

if 1 in {x, y, z}:

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

を使用すると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'truthy'である最初の引数に評価されFalseます。たとえば、数値0または空ではありません(ブール式のコンテキストでPythonがfalseと見なすものの詳細については、ブール式を参照してください)。

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

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

96
dansalmo 2013-07-12 11:56.

次のような辞書構造を使用すると、問題に簡単に対処できます。

x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]
67
ThatGuyRussell 2015-08-19 16:34.

Martijn Pietersが述べているように、正確で最速のフォーマットは次のとおりです。

if 1 in {x, y, z}:

if文の彼のアドバイスを使用して、あなたは今、Pythonが、前者はなかったかどうかをそれぞれの文を読みますので、別々のだろうTrueFalse。といった:

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])
46
akaRem 2013-07-12 11:16.

直接書く方法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)

ところで、たくさんのifsはこのようなものとして書くことができます

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
35
ytpillai 2015-05-25 17:53.

非常に怠惰な場合は、値を配列内に配置できます。といった

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ステートメントよりもはるかに複雑です。それはあなたが余分な怠惰になろうとすることで得られるものです:)

もう一つ、あなたの

if x or y or z == 0:

コンパイルされますが、希望する方法ではありません。ifステートメントに変数を入れるだけの場合(例)

if b

プログラムは、変数がnullでないかどうかを確認します。上記のステートメントを書く別の方法(より理にかなっています)は

if bool(b)

Boolは、基本的にブールステートメントを検証するコマンドを実行するPythonの組み込み関数です(それが何であるかわからない場合は、今すぐifステートメントで作成しようとしているものです:))

私が見つけたもう一つの怠惰な方法は:

if any([x==0, y==0, z==0])
33
GuiltyDolphin 2014-06-05 07:09.

値が変数のセットに含まれているかどうかを確認するには、組み込みモジュールitertoolsとを使用できます operator

例えば:

輸入:

from itertools import repeat
from operator import contains

変数を宣言します:

x = 0
y = 1
z = 3

値のマッピングを(確認したい順序で)作成します。

check_values = (0, 1, 3)

itertools変数の繰り返しを許可するために使用します。

check_vars = repeat((x, y, z))

最後に、map関数を使用してイテレータを作成します。

checker = map(contains, check_vars, check_values)

次に、(元の順序で)値を確認するときに、次を使用しますnext()

if next(checker)  # Checks for 0
    # Do something
    pass
elif next(checker)  # Checks for 1
    # Do something
    pass

等...

これは、以上の利点があるlambda x: x in (variables)ためでoperator作り付けのモジュールであり、より速く、より効率的に使用するよりもlambda、カスタムインプレース関数を作成していました。

リストにゼロ以外(またはFalse)の値があるかどうかを確認するための別のオプション:

not (x and y and z)

同等:

not all((x, y, z))
31
B. M. 2015-06-10 10:46.

Setはここでの良いアプローチです。なぜなら、ここでの目標は変数を順序付けるからです。パラメータの順序{z,y,x}{0,1,3}何でもです。

>>> ["cdef"[i] for i in {z,x,y}]
['c', 'd', 'f']

このように、ソリューション全体はO(n)です。

31
Rolf of Saxony 2016-09-11 05:44.

ここで提供される優れた回答はすべて、元のポスターの特定の要件に集中し、if 1 in {x,y,z}MartijnPietersによって提案されたソリューションに集中しています。
彼らが無視しているのは、質問のより広い意味
です。複数の値に対して1つの変数をテストするにはどうすればよいですか。
提供されているソリューションは、たとえば文字列を使用している場合、部分ヒットでは機能しません。
文字列「Wild」が複数の値にあるかどうかをテストします。

>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in {x, y, z}: print (True)
... 

または

>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in [x, y, z]: print (True)
... 

このシナリオでは、文字列に変換するのが最も簡単です

>>> [x, y, z]
['Wild things', 'throttle it back', 'in the beginning']
>>> {x, y, z}
{'in the beginning', 'throttle it back', 'Wild things'}
>>> 

>>> if "Wild" in str([x, y, z]): print (True)
... 
True
>>> if "Wild" in str({x, y, z}): print (True)
... 
True

ただし、で述べたように@codeforester、次のように、このメソッドでは単語の境界が失われることに注意してください。

>>> x=['Wild things', 'throttle it back', 'in the beginning']
>>> if "rot" in str(x): print(True)
... 
True

3文字rotはリストに組み合わせて存在しますが、個別の単語としては存在しません。「rot」のテストは失敗しますが、リスト項目の1つが「rotin hell」の場合、それも失敗します。
結果として、この方法を使用する場合は検索条件に注意し、この制限があることに注意してください。

30
Bhargav Boda 2015-01-14 02:10.

私はこれがそれをよりよく処理すると思います:

my_dict = {0: "c", 1: "d", 2: "e", 3: "f"}

def validate(x, y, z):
    for ele in [x, y, z]:
        if ele in my_dict.keys():
            return my_dict[ele]

出力:

print validate(0, 8, 9)
c
print validate(9, 8, 9)
None
print validate(9, 8, 2)
e
30
hamid 2015-04-10 17:29.

ifを使用する場合は、次のelseステートメントが別の解決策です。

myList = []
aList = [0, 1, 3]

for l in aList:
    if l==0: myList.append('c')
    elif l==1: myList.append('d')
    elif l==2: myList.append('e')
    elif l==3: myList.append('f')

print(myList)
26
Saksham Varma 2015-02-27 15:31.
d = {0:'c', 1:'d', 2:'e', 3: 'f'}
x, y, z = (0, 1, 3)
print [v for (k,v) in d.items() if x==k or y==k or z==k]
26
michael zxc858 2015-06-29 21:03.

このコードは役立つかもしれません

L ={x, y, z}
T= ((0,"c"),(1,"d"),(2,"e"),(3,"f"),)
List2=[]
for t in T :
if t[0] in L :
    List2.append(t[1])
    break;
12
Siddharth Satpathy 2018-12-03 19:13.

以下の方法を試すことができます。この方法では、入力したい変数の数を自由に指定/入力できます。

mydict = {0:"c", 1:"d", 2:"e", 3:"f"}
mylist= []

num_var = int(raw_input("How many variables? ")) #Enter 3 when asked for input.

for i in range(num_var): 
    ''' Enter 0 as first input, 1 as second input and 3 as third input.'''
    globals()['var'+str('i').zfill(3)] = int(raw_input("Enter an integer between 0 and 3 "))
    mylist += mydict[globals()['var'+str('i').zfill(3)]]

print mylist
>>> ['c', 'd', 'f']
10
Vinayak Kaniyarakkal 2017-06-05 20:50.

ワンラインソリューション:

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

または:

mylist = ['cdef'[i] for i in range(4) if i in (x, y, z)]
9
Sergei 2019-02-18 07:55.

たぶん、出力ビットセットの直接式が必要です。

x=0 or y=0 or z=0   is equivalent to x*y*z = 0

x=1 or y=1 or z=1   is equivalent to (x-1)*(y-1)*(z-1)=0

x=2 or y=2 or z=2   is equivalent to (x-2)*(y-2)*(z-2)=0

ビットにマッピングしましょう: 'c':1 'd':0xb10 'e':0xb100 'f':0xb1000

iscの関係(is'c '):

if xyz=0 then isc=1 else isc=0

数式https://youtu.be/KAdKCgBGK0k?list=PLnI9xbPdZUAmUL8htSl6vToPQRRN3hhFp&t=315の場合は数学を使用します

[c]: (xyz=0 and isc=1) or (((xyz=0 and isc=1) or (isc=0)) and (isc=0))

[d]: ((x-1)(y-1)(z-1)=0 and isc=2) or (((xyz=0 and isd=2) or (isc=0)) and (isc=0))

..。

次のロジックでこれらの式を接続します。

  • 論理andは方程式の二乗の合計です
  • 論理orは方程式の積です

合計を表す合計方程式があり、合計の合計式があります。

次に、sum&1はc、sum&2はd、sum&4はe、sum&5はfです。

この後、文字列要素のインデックスが準備完了文字列に対応する事前定義された配列を形成できます。

array[sum] あなたに文字列を与えます。

8
rsalmei 2018-08-06 20:26.

Pythonで擬似コードを表現する最もPython的な方法は、次のとおりです。

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

if any(v == 0 for v in (x, y, z)):
    mylist.append("c")
if any(v == 1 for v in (x, y, z)):
    mylist.append("d")
if any(v == 2 for v in (x, y, z)):
    mylist.append("e")
if any(v == 3 for v in (x, y, z)):
    mylist.append("f")
7
Seenivasan 2018-11-07 04:26.

それは簡単に行うことができます

for value in [var1,var2,var3]:
     li.append("targetValue")
5
alamin 2018-09-20 16:18.

1つの値で複数の変数をテストするには: if 1 in {a,b,c}:

1つの変数で複数の値をテストするには: if a in {1, 2, 3}:

4
firelynx 2018-08-27 23:45.

ある種のシーザー暗号を構築しているようです。

より一般化されたアプローチはこれです:

input_values = (0, 1, 3)
origo = ord('c')
[chr(val + origo) for val in inputs]

出力

['c', 'd', 'f']

それがコードの望ましい副作用であるかどうかはわかりませんが、出力の順序は常に並べ替えられます。

これが必要な場合は、最終行を次のように変更できます。

sorted([chr(val + origo) for val in inputs])
3
Massifox 2019-10-12 02:17.

口述なしで、この解決策を試してください:

x, y, z = 0, 1, 3    
offset = ord('c')
[chr(i + offset) for i in (x,y,z)]

そして与える:

['c', 'd', 'f']
2
Rohit Gawas 2018-08-01 06:54.

あなたは辞書を使うことができます:

x = 0
y = 1
z = 3
list=[]
dict = {0: 'c', 1: 'd', 2: 'e', 3: 'f'}
if x in dict:
    list.append(dict[x])
else:
    pass

if y in dict:
    list.append(dict[y])
else:
    pass
if z in dict:
    list.append(dict[z])
else:
    pass

print list
0
Mayur 2019-04-06 12:03.

これはあなたを助けます。

def test_fun(val):
    x = 0
    y = 1
    z = 2
    myList = []
    if val in (x, y, z) and val == 0:
        myList.append("C")
    if val in (x, y, z) and val == 1:
        myList.append("D")
    if val in (x, y, z) and val == 2:
        myList.append("E")

test_fun(2);
0
Serhii 2019-09-10 08:23.

あなたはこれを団結させることができます

x = 0
y = 1
z = 3

1つの変数で。

In [1]: xyz = (0,1,3,) 
In [2]: mylist = []

次のように条件を変更します。

In [3]: if 0 in xyz: 
    ...:     mylist.append("c") 
    ...: if 1 in xyz: 
    ...:     mylist.append("d") 
    ...: if 2 in xyz: 
    ...:     mylist.append("e") 
    ...: if 3 in xyz:  
    ...:     mylist.append("f") 

出力:

In [21]: mylist                                                                                
Out[21]: ['c', 'd', 'f']
0
fhgd 2019-11-07 01:11.

問題

複数の値をテストするためのパターンが

>>> 2 in {1, 2, 3}
True
>>> 5 in {1, 2, 3}
False

非常に読みやすく、多くの状況で機能しています。1つの落とし穴があります。

>>> 0 in {True, False}
True

でも欲しい

>>> (0 is True) or (0 is False)
False

解決

前の式の一般化の1つは、ytpillaiからの回答に基づいています。

>>> any([0 is True, 0 is False])
False

これは次のように書くことができます

>>> any(0 is item for item in (True, False))
False

この式は正しい結果を返しますが、最初の式ほど読みやすくはありません:-(

Related questions

MORE COOL STUFF

「水曜日」シーズン1の中心には大きなミステリーがあります

「水曜日」シーズン1の中心には大きなミステリーがあります

Netflixの「水曜日」は、典型的な10代のドラマ以上のものであり、実際、シーズン1にはその中心に大きなミステリーがあります.

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ボディーランゲージの専門家は、州訪問中にカミラ・パーカー・ボウルズが輝くことを可能にした微妙なケイト・ミドルトンの動きを指摘しています

ケイト・ミドルトンは、州の夕食会と州の訪問中にカミラ・パーカー・ボウルズからスポットライトを奪いたくなかった、と専門家は言う.

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンがハリー・スタイルズとオリビア・ワイルドの「非常に友好的な」休憩が永続的であることを望んでいる理由

一部のファンが、オリビア・ワイルドが彼女とハリー・スタイルズとの間の「難しい」が「非常に友好的」な分割を恒久的にすることを望んでいる理由を見つけてください.

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンはまだ「非常に困難な時期」を過ごしている、と王室の専門家が明らかにする 

エリザベス女王の死後、ケイト・ミドルトンが舞台裏で「非常に困難な時期」を過ごしていたと伝えられている理由を調べてください.

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セントヘレナのジェイコブのはしごを登るのは、気弱な人向けではありません

セント ヘレナ島のジェイコブズ ラダーは 699 段の真っ直ぐ上る階段で、頂上に到達すると証明書が発行されるほどの難易度です。

The Secrets of Airline Travel Quiz

The Secrets of Airline Travel Quiz

Air travel is far more than getting from point A to point B safely. How much do you know about the million little details that go into flying on airplanes?

Where in the World Are You? Take our GeoGuesser Quiz

Where in the World Are You? Take our GeoGuesser Quiz

The world is a huge place, yet some GeoGuessr players know locations in mere seconds. Are you one of GeoGuessr's gifted elite? Take our quiz to find out!

バイオニック読書はあなたをより速く読むことができますか?

バイオニック読書はあなたをより速く読むことができますか?

BionicReadingアプリの人気が爆発的に高まっています。しかし、それは本当にあなたを速読術にすることができますか?

Total War:Warhammer:Kotakuレビュー

Total War:Warhammer:Kotakuレビュー

私はこのゲームを嫌う準備ができていました。先週の前に、Total War:Warhammerについての私の考えがありました:それでもここに私は、私の手にある完成品であり、私は変わった男です。

涙の道:軍事化された帝国主義勢力がスタンディングロックキャンプを占領

涙の道:軍事化された帝国主義勢力がスタンディングロックキャンプを占領

スタンディングロックスー族のメンバーと水の保護者は、ノースダコタ州のスタンディングロックにあるオセティサコウィンキャンプを去ります。(Twitter経由のCNNスクリーンショット)火と煙がスカイラインを覆い、スタンディングロックスー族のメンバーと水の保護者が、聖なるものを守りながら建てた家、オセティサコウィン(セブンカウンシルファイアーズ)キャンプから行進し、太鼓を打ち、歌い、祈りました。ダコタアクセスパイプラインとしても知られる「ブラックスネーク」からの土地。

シアーズとKマートはイヴァンカ・トランプの商品を自分たちで取り除いています

シアーズとKマートはイヴァンカ・トランプの商品を自分たちで取り除いています

写真:APシアーズとKマートは、イヴァンカ・トランプのトランプホームアイテムのコレクションも、誰も購入したくないために削除しました。シアーズとKマートの両方の親会社であるシアーズホールディングスは、土曜日のABCニュースへの声明で、彼らが気にかけていると辛抱強く説明しましたトランプラインを売り続けるにはお金を稼ぐことについてあまりにも多く。

ポテトチップスでたった10分でスペインのトルティーヤを作る

ポテトチップスでたった10分でスペインのトルティーヤを作る

伝統的なスペインのトルティーヤは通常、オリーブオイルで柔らかくなるまで調理されたポテトから始まります(30分以上かかる場合があります)が、ケトルで調理されたポテトチップスの助けを借りてわずか10分でテーブルに置くことができます。上のビデオはすべてがバラバラにならないように裏返す方法を含め、レシピ全体を説明しますが、必要なのは4〜5個の卵と3カップのケトルチップスだけです。

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、彼らが子供たちと行っているスパイをテーマにした活動を共有しています

ケイト・ミドルトンとウィリアム王子は、子供向けのパズルの本の序文を書き、ジョージ王子、シャーロット王女、ルイ王子と一緒にテキストを読むと述べた.

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

事故で押しつぶされたスイカは、動物を喜ばせ水分補給するために野生生物保護団体に寄付されました

Yak's Produce は、数十個のつぶれたメロンを野生動物のリハビリ専門家であるレスリー グリーンと彼女のルイジアナ州の救助施設で暮らす 42 匹の動物に寄付しました。

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

デミ・ロヴァートは、新しいミュージシャンのボーイフレンドと「幸せで健康的な関係」にあります: ソース

8 枚目のスタジオ アルバムのリリースに向けて準備を進めているデミ ロヴァートは、「スーパー グレート ガイ」と付き合っている、と情報筋は PEOPLE に確認しています。

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

Plathville の Kim と Olivia Plath が数年ぶりに言葉を交わすことへようこそ

イーサン プラスの誕生日のお祝いは、TLC のウェルカム トゥ プラスビルのシーズン 4 のフィナーレで、戦争中の母親のキム プラスと妻のオリビア プラスを結びつけました。

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

仕事の生産性を高める 8 つのシンプルなホーム オフィスのセットアップのアイデア

ホームオフィスのセットアップ術を極めよう!AppExert の開発者は、家族全員が一緒にいる場合でも、在宅勤務の技術を習得しています。祖父や曽祖父が共同家族で暮らしていた頃の記憶がよみがえりました。

2022 年、私たちのデジタル ライフはどこで終わり、「リアル ライフ」はどこから始まるのでしょうか?

20 年前のタイムトラベラーでさえ、日常生活におけるデジタルおよびインターネットベースのサービスの重要性に驚くことでしょう。MySpace、eBay、Napster などのプラットフォームは、高速化に焦点を合わせた世界がどのようなものになるかを示してくれました。

ニューロマーケティングの秘密科学

ニューロマーケティングの秘密科学

マーケティング担当者が人間の欲望を操作するために使用する、最先端の (気味が悪いと言う人もいます) メソッドを探ります。カートをいっぱいにして 3 桁の領収書を持って店を出る前に、ほんの数点の商品を買いに行ったことはありませんか? あなたは一人じゃない。

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

地理情報システムの日: GIS 開発者として学ぶべき最高の技術スタック

私たちが住んでいる世界を確実に理解するには、データが必要です。ただし、空間参照がない場合、このデータは地理的コンテキストがないと役に立たなくなる可能性があります。

Language