web-dev-qa-db-ja.com

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

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

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

541
user1877442

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

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

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

Tuple に対する包含テストを使用すると、短くすることができます。

if 1 in (x, y, z):

もっと良いですか。

if 1 in {x, y, z}:

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

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

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

ただし、これがではなく、式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 = 0の場合、x or y or z2に解決されます。これが、引数の最初の真のような値だからです。 2 == 1Falseになりますが、y == 1Trueになります。

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

711
Martijn Pieters

あなたの問題は、次のような辞書構造でより簡単に対処できます。

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

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")
...

これはうまくいきますが、ifあなたが辞書を使うのに慣れているなら(私がしたことを見てください)、最初の辞書で数字を望みの文字に対応付けることできれいにできます。ループ:

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])
55
ThatGuyRussell

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
40
akaRem

あなたがとても怠け者なら、あなたは配列の中に値を置くことができます。といった

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])
28
ytpillai

値が一連の変数に含まれているかどうかを確認するには、組み込みモジュール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

等...

operatorは組み込みモジュールであり、カスタムインプレース関数を作成する必要があるlambdaを使用するよりも高速で効率的であるため、これはlambda x: x in (variables)よりも有利です。

リストにゼロ以外(またはFalse)の値があるかどうかを調べるためのもう1つのオプション:

not (x and y and z)

同値:

not all((x, y, z))
26
GuiltyDolphin

ここで提供される優れた答えはすべて、元のポスターの特定の要件に集中し、Martijn Pietersによって提案されたif 1 in {x,y,z}ソリューションに集中することです。
彼らが無視しているのは、質問のより広い意味合いです。
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で述べられているように、この方法ではWordの境界が失われることに注意してください。

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

3文字のrotは、リスト内に組み合わせて存在しますが、個々のWordとしては存在しません。 "rot"のテストは失敗しますが、リスト項目の1つが "rot in hell"の場合、それも失敗します。
そのため、この方法を使用する場合は検索条件に注意し、この制限があることに注意してください。

24
Rolf of Saxony

Ifを使いたいのであれば、他に以下のステートメントがあります。

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)
24
hamid

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

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
24
Bhargav Boda

Setはここでは良いアプローチです、それは変数を順序付けるので、ここであなたの目標と思われるものです。 {z,y,x}は、パラメータの順序にかかわらず{0,1,3}です。

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

このように、全体の解はO(n)です。

24
B. M.

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

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;
21
michael zxc858
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]
21
Saksham Varma

1行ソリューション

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)]

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

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']
6

たぶんあなたはセットされた出力ビットのための直接公式が必要です。

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]はあなたに文字列を渡します。

4
Sergei

それは容易にすることができます

for value in [var1,var2,var3]:
     li.append("targetValue")
4
Seenivasan

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

もっと一般化されたアプローチはこれです:

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
firelynx

これはあなたを助けるでしょう。

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);
3
Mayur

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

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

3

疑似コードを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")
3
rsalmei

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

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
1
Rohit Gawas