如何针对值测试多个变量?

时间:2013-02-27 12:26:23

标签: python if-statement comparison match boolean-logic

我正在尝试创建一个将多个变量与一个整数进行比较并输出三个字母的字符串的函数。我想知道是否有办法将其翻译成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"]

这样的事情可能吗?

27 个答案:

答案 0 :(得分:722)

你误解了布尔表达式的工作原理;他们不像英语句子一样工作,并猜测你在谈论所有名字的相同比较。您正在寻找:

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

xy会自行评估(如果False则为0,否则为True

您可以使用针对a tuple的遏制测试来缩短它:

if 1 in (x, y, z):

或更好:

if 1 in {x, y, z}:

使用a set来利用常量成本成员资格测试(无论左侧操作数是什么,in都需要一定的时间。)

当您使用or时,python会将运算符的每一侧视为单独的表达式。表达式x or y == 1首先被视为x的布尔测试,如果为False,则表达式y == 1被测试。

这是由于operator precedenceor运算符的优先级低于==运算符,因此后者首先计算

但是,即使这个,并且表达式x or y or z == 1实际上被解释为(x or y or z) == 1,这仍然不会按照您的预期执行。

x or y or z将评估第一个参数'truthy',例如不是False,数字0或空(有关Python在布尔上下文中认为false的详细信息,请参阅boolean expressions。)

因此,对于值x = 2; y = 1; z = 0x or y or z将解析为2,因为这是参数中第一个类似于true的值。然后2 == 1False,即使y == 1True

同样适用于逆;针对单个变量测试多个值; x == 1 or 2 or 3因同样的原因会失败。使用x == 1 or x == 2 or x == 3x in {1, 2, 3}

答案 1 :(得分:85)

使用字典结构更容易解决您的问题:

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

答案 2 :(得分:56)

正如Martijn Pieters所说,正确且最快的格式是:

if 1 in {x, y, z}:

使用他的建议你现在会有单独的if语句,这样Python就会读取每个语句,无论前者是True还是False。如:

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

答案 3 :(得分:42)

编写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)

BTW很多if可以写成像这样的东西

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

答案 4 :(得分:29)

如果你非常懒,可以将值放在数组中。如

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 x or y or z == 0:

将编译,但不会按照您希望的方式编译。当你只是在if语句中放一个变量(例子)

if b

程序将检查变量是否为空。编写上述语句的另一种方法(更有意义)是

if bool(b)

Bool是python中的一个内置函数,它基本上执行验证布尔语句的命令(如果你不知道那是什么,那么你现在正试着在你的if语句中做:) :)

我发现的另一种懒惰方式是:

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

答案 5 :(得分:27)

要检查一组变量中是否包含值,您可以使用内置模块itertoolsoperator

例如:

进口:

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

答案 6 :(得分:25)

这里提供的所有优秀答案都集中在原始海报的具体要求上,并专注于Martijn Pieters提出的if 1 in {x,y,z}解决方案。
他们忽略的是这个问题的更广泛的含义:
如何针对多个值测试一个变量?
如果使用字符串,则提供的解决方案不适用于部分命中:
测试字符串“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确实在列表中组合存在,但不作为单个单词存在。对“腐烂”的测试会失败,但如果其中一个列表项目“腐烂地狱”,那也会失败 结果是,如果使用此方法,请注意您的搜索条件,并注意它确实有此限制。

答案 7 :(得分:25)

Set是一个很好的方法,因为它对变量进行排序,这似乎是你的目标。无论参数的顺序如何,{z,y,x}都是{0,1,3}

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

这样,整个解决方案就是O(n)。

答案 8 :(得分:25)

如果你想使用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)

答案 9 :(得分:25)

我认为这会更好地处理它:

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

答案 10 :(得分:22)

此代码可能会有所帮助

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;

答案 11 :(得分:22)

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]

答案 12 :(得分:7)

一线解决方案:

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

答案 13 :(得分:6)

您可以尝试以下显示的方法。在这种方法中,您可以自由指定/输入要输入的变量数。

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

答案 14 :(得分:5)

也许您需要直接的公式来设置输出位。

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(是'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]为您提供字符串。

答案 15 :(得分:4)

可以很容易地完成

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

答案 16 :(得分: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")

答案 17 :(得分:3)

看起来您正在构建某种凯撒密码。

更通用的方法是:

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

答案 18 :(得分:3)

要用一个值测试多个变量:if 1 in {a,b,c}:

要使用一个变量测试多个值:if a in {1, 2, 3}:

答案 19 :(得分:3)

这将为您提供帮助。

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

答案 20 :(得分:2)

没有字典,请尝试以下解决方案:

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

并给出:

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

答案 21 :(得分:1)

您可以使用字典:

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

答案 22 :(得分:0)

您可以团结起来

x = 0
y = 1
z = 3

在一个变量中。

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

答案 23 :(得分:0)

or 不像 explained by this answer 那样工作。

虽然将使用通用答案

if 0 in (x, y, z):
    ...

这不是解决特定问题的最佳方法。在您的情况下,您正在执行重复测试,因此组合这些变量的是值得的:

values = {x, y, z}

if 0 in values:
    mylist.append("c")

if 1 in values:
    mylist.append("d")

我们可以使用字典来简化它——这将产生相同的值:

mappings = {0: "c", 1: "d", ...}
for k in mappings:
    if k in values:
        mylist.append(mappings[k])

或者,如果 mylist 的顺序是任意的,您可以循环遍历 values 并将它们与映射匹配:

mappings = {0: "c", 1: "d", ...}
for v in (x, y, z):
    if v in mappings:
        mylist.append(mappings[v])

答案 24 :(得分:-1)

问题

用于测试多个值的模式

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

可读性很强,并且在许多情况下都可以使用,但有一个陷阱:

>>> 0 in {True, False}
True

但是我们想要拥有

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

解决方案

先前表达式的一种概括是基于ytpillai的答案:

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

可以写为

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

尽管此表达式返回正确的结果,但其可读性不如第一个表达式:-(

答案 25 :(得分:-1)

您可以通过两种方式开发它

    def compareVariables(x,y,z):
        mylist = []
        if x==0 or y==0 or z==0:
            mylist.append('c')
        if  x==1 or y==1 or z==1:
            mylist.append('d')
        if  x==2 or y==2 or z==2:
            mylist.append('e')
        if  x==3 or y==3 or z==3:
            mylist.append('f')
        else:
            print("wrong input value!")
        print('first:',mylist)

        compareVariables(1, 3, 2)

    def compareVariables(x,y,z):
        mylist = []
        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 3 in (x,y,z):
             mylist.append('f')
        else:
             print("wrong input value!")
        print('second:',mylist)

        compareVariables(1, 3, 2)

答案 26 :(得分:-1)

这是另一种方法:

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

if any(i in [0] for i in[x,y,z]):
    mylist.append("c")
if any(i in [1] for i in[x,y,z]):
    mylist.append("d")
if any(i in [2] for i in[x,y,z]):
    mylist.append("e")
if any(i in [3] for i in[x,y,z]):
    mylist.append("f")

它是列表理解任何关键字的混合。