如何根据值testing多个variables?
我试图做一个函数,将多个variables比较为一个整数,并输出一个三个字母的string。 我想知道是否有办法将其转换为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"]
是这样的可能吗?
你误解了布尔expression式是如何工作的。 他们不会像英文句子一样工作,并猜测你在这里谈论所有名字的相同比较。 您正在寻找:
if x == 1 or y == 1 or z == 1:
否则x
和y
会自行评估(如果为0
,则为False
,否则为True
)。
你可以缩短到:
if 1 in (x, y, z):
或更好:
if 1 in {x, y, z}:
使用一set
来利用恒定成本的成员资格testing(无论左手操作数是多less,都需要一定的时间)。
当你使用or
,python将运算符的每一侧视为单独的expression式。 expression式x or y == 1
被视为x
第一个布尔testing,那么如果它是False,则testingexpression式y == 1
。
这是由于运营商的优先权 。 or
运算符的优先级低于==
testing,所以后者首先被评估。
但是,即使情况并非如此,expression式x or y or z == 1
实际上被解释为(x or y or z) == 1
,但是这仍然不能达到你期望的效果。
x or y or z
会计算出第一个参数“truthy”,例如not False
,numeric 0或者空值(关于Python在布尔上下文中认为false的细节,请参考布尔expression式 )。
所以对于值x = 2; y = 1; z = 0
x = 2; y = 1; z = 0
x = 2; y = 1; z = 0
, x or y or z
将parsing为2
,因为这是参数中第一个类似于真的值。 那么2 == 1
将是False
,即使y == 1
将是True
。
反过来也一样。 针对单个variablestesting多个值; x == 1 or 2 or 3
会出于同样的原因失败。 x in {1, 2, 3}
使用x == 1 or x == 2 or x == 3
或x in {1, 2, 3}
。
你的问题更容易用字典结构解决,如:
x = 0 y = 1 z = 3 d = {0: 'c', 1:'d', 2:'e', 3:'f'} mylist = [d[k] for k in [x, y, z]]
以前的解决scheme:正如Martijn Pieters所说,正确和最快的格式是:
if 1 in {x, y, z}:
似乎没有解决的一个主要问题是,你希望你的输出列表包含每个字母后真正的if语句。
只使用Martijn Pieters的build议,你现在可以:
if 0 in {x, y, z}: Mylist.append("c") elif 1 in {x, y, z}: Mylist.append("d") ...
问题:第一个if语句将返回true,并且永远不会得到以下elif语句。 所以你的清单会简单地返回:
["c"]
你想要的是有单独的if语句,以便python将读取每个语句,无论前者是真的还是假的。 如:
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'循环:
numToLetters = {0:"c", 1:"d", 2:"e", 3:"f"} for number in numToLetters: if number in {x, y, z}: Mylist.append(numToLetters[number])
直接写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
可以写成这样的东西
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
如果你非常懒,你可以把值放在一个数组中。 如
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:
将编译,但不是你想要的方式。 当你简单地把一个variables放在if语句中(例子)
if b
程序将检查variables是否不为空。 另一种方式来写上述语句(这更有意义)是
if bool(b)
Bool是一个内置的python函数,它基本上是validation一个布尔语句的命令(如果你不知道这是什么,那么这就是你现在要做的if语句:)
我发现另一个懒惰的方式是:
if any([x==0, y==0, z==0])
要检查一组variables中是否包含一个值,可以使用内置模块itertools
和operator
。
例如:
import:
from itertools import repeat from operator import contains
声明variables:
x = 0 y = 1 z = 3
创build值的映射(按照您要检查的顺序):
check_values = (0, 1, 3)
使用itertools
来允许重复的variables:
check_vars = repeat((x, y, z))
最后,使用map
函数来创build一个迭代器:
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
创build一个自定义就地function更快,更高效。
另一种检查列表中是否有非零(或False)值的选项:
not (x and y and z)
当量:
not all((x, y, z))
我认为这会更好地处理:
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
如果你想使用if语句,else语句是另一个解决scheme:
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)
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]
此代码可能会有所帮助
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;
Set是这里的好方法,因为它命令variables,这里你的目标似乎是什么。 无论参数的顺序如何{z,y,x}
都是{0,1,3}
。
>>> [chr(ord('c')+i) for i in {z,x,y}] ['c', 'd', 'f']
与数字相对应的字母在这里由chr(ord('c')+i)
,其中chr
和ord
是字符和数字代码之间的桥梁。
所以整个解决scheme是O(n)。
这里提供的所有优秀答案集中在原始海报的具体要求上,集中在Martijn Pieters提出的if 1 in {x,y,z}
解中的if 1 in {x,y,z}
。
他们忽视的是这个问题的更广泛的含义:
我如何testing一个variables对多个值?
如果使用string,提供的解决scheme不适用于部分匹配:
testingstring“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) ...
对于这种情况,最简单的方法就是转换成string
>>> [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
一行解决scheme:
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)]
不要太复杂,只要按照最简单的方法。
x = 0 y = 1 z = 3 Mylist = [] if x == 0 or y==0 or z==0: Mylist.append('c') elif x == 1 or y == 1 or z==1: Mylist.append('d') elif x==2 or y==2 or z==2: Mylist.append('e') elif x==3 or y==3 or z==3: Mylist.append('f')
干杯!