Python 如何针对一个值测试多个变量?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15112125/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to test multiple variables against a value?
提问by user1877442
I'm trying to make a function that will compare multiple variables to an integer and output a string of three letters. I was wondering if there was a way to translate this into Python. So say:
我正在尝试制作一个函数,它将多个变量与一个整数进行比较并输出一个由三个字母组成的字符串。我想知道是否有办法将其翻译成 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")
which would return a list of:
这将返回一个列表:
["c", "d", "f"]
Is something like this possible?
这样的事情可能吗?
采纳答案by Martijn Pieters
You misunderstand how boolean expressions work; they don't work like an English sentence and guess that you are talking about the same comparison for all names here. You are looking for:
你误解了布尔表达式的工作原理;它们不像英语句子那样工作,并且猜测您在这里谈论的是所有名称的相同比较。您正在寻找:
if x == 1 or y == 1 or z == 1:
xand yare otherwise evaluated on their own (Falseif 0, Trueotherwise).
x并y以其他方式自行评估(False如果0,True否则)。
You can shorten that using a containment test against a tuple:
您可以使用针对元组的包含测试来缩短它:
if 1 in (x, y, z):
or better still:
或者更好:
if 1 in {x, y, z}:
using a setto take advantage of the constant-cost membership test (intakes a fixed amount of time whatever the left-hand operand is).
使用aset来利用恒定成本成员资格测试(in无论左侧操作数是什么,都需要固定的时间)。
When you use or, python sees each side of the operator as separateexpressions. The expression x or y == 1is treated as first a boolean test for x, then if that is False, the expression y == 1is tested.
当您使用 时or,python 将运算符的每一侧视为单独的表达式。该表达式x or y == 1首先被视为 的布尔测试x,然后如果为 False,y == 1则测试该表达式。
This is due to operator precedence. The oroperator has a lower precedence than the ==test, so the latter is evaluated first.
这是由于运算符优先级。的or操作者具有较低的优先级比所述==测试,所以后者被评估第一。
However, even if this were notthe case, and the expression x or y or z == 1was actually interpreted as (x or y or z) == 1instead, this would still not do what you expect it to do.
然而,即使情况并非如此,并且表达式x or y or z == 1实际上被解释为(x or y or z) == 1相反,这仍然不会做你期望它做的事情。
x or y or zwould evaluate to the first argument that is 'truthy', e.g. not False, numeric 0 or empty (see boolean expressionsfor details on what Python considers false in a boolean context).
x or y or z将评估为“真实”的第一个参数,例如 not False、数字 0 或空(有关 Python 在布尔上下文中认为 false 的详细信息,请参阅布尔表达式)。
So for the values x = 2; y = 1; z = 0, x or y or zwould resolve to 2, because that is the first true-like value in the arguments. Then 2 == 1would be False, even though y == 1would be True.
因此对于 values x = 2; y = 1; z = 0,x or y or z将解析为2,因为这是参数中的第一个类似 true 的值。然后2 == 1会是False,即使y == 1会是True。
The same would apply to the inverse; testing multiple values against a single variable; x == 1 or 2 or 3would fail for the same reasons. Use x == 1 or x == 2 or x == 3or x in {1, 2, 3}.
这同样适用于逆;针对单个变量测试多个值;x == 1 or 2 or 3会因为同样的原因而失败。使用x == 1 or x == 2 or x == 3或x in {1, 2, 3}。
回答by akaRem
The direct way to write x or y or z == 0is
直接的写法x or y or z == 0是
if any(map((lambda value: value == 0), (x,y,z))):
pass # write your logic.
But I dont think, you like it. :) And this way is ugly.
但我不认为,你喜欢它。:) 这种方式很丑陋。
The other way (a better) is:
另一种方式(更好)是:
0 in (x, y, z)
BTW lots of ifs could be written as something like this
顺便说一句,很多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
回答by dansalmo
Your problem is more easily addressed with a dictionary structure like:
使用字典结构可以更轻松地解决您的问题,例如:
x = 0
y = 1
z = 3
d = {0: 'c', 1:'d', 2:'e', 3:'f'}
mylist = [d[k] for k in [x, y, z]]
回答by GuiltyDolphin
To check if a value is contained within a set of variables you can use the inbuilt modules itertoolsand operator.
要检查值是否包含在一组变量中,您可以使用内置模块 itertools和operator.
For example:
例如:
Imports:
进口:
from itertools import repeat
from operator import contains
Declare variables:
声明变量:
x = 0
y = 1
z = 3
Create mapping of values (in the order you want to check):
创建值的映射(按照您要检查的顺序):
check_values = (0, 1, 3)
Use itertoolsto allow repetition of the variables:
使用itertools允许的变量重复:
check_vars = repeat((x, y, z))
Finally, use the mapfunction to create an iterator:
最后,使用该map函数创建一个迭代器:
checker = map(contains, check_vars, check_values)
Then, when checking for the values (in the original order), use next():
然后,在检查值时(按原始顺序),使用next():
if next(checker) # Checks for 0
# Do something
pass
elif next(checker) # Checks for 1
# Do something
pass
etc...
等等...
This has an advantage over the lambda x: x in (variables)because operatoris an inbuilt module and is faster and more efficient than using lambdawhich has to create a custom in-place function.
这比lambda x: x in (variables)因为operator是内置模块具有优势,并且比使用lambda它必须创建自定义就地功能更快、更有效。
Another option for checking if there is a non-zero (or False) value in a list:
检查列表中是否存在非零(或假)值的另一种选择:
not (x and y and z)
Equivalent:
相等的:
not all((x, y, z))
回答by Bhargav Boda
I think this will handle it better:
我认为这会更好地处理它:
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]
Output:
输出:
print validate(0, 8, 9)
c
print validate(9, 8, 9)
None
print validate(9, 8, 2)
e
回答by Saksham Varma
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]
回答by hamid
If you want to use if, else statements following is another solution:
如果要使用 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)
回答by ytpillai
If you ARE very very lazy, you can put the values inside an array. Such as
如果您非常非常懒惰,则可以将值放入数组中。如
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
You can also put the numbers and letters in a dictionary and do it, but this is probably a LOT more complicated than simply if statements. That's what you get for trying to be extra lazy :)
您也可以将数字和字母放入字典中并进行操作,但这可能比简单的 if 语句复杂得多。这就是你试图变得特别懒惰的结果:)
One more thing, your
还有一件事,你的
if x or y or z == 0:
will compile, but not in the way you want it to. When you simply put a variable in an if statement (example)
将编译,但不是以您希望的方式编译。当您简单地将变量放入 if 语句中时(示例)
if b
the program will check if the variable is not null. Another way to write the above statement (which makes more sense) is
程序将检查变量是否不为空。编写上述语句的另一种方法(更有意义)是
if bool(b)
Bool is an inbuilt function in python which basically does the command of verifying a boolean statement (If you don't know what that is, it is what you are trying to make in your if statement right now :))
Bool 是 python 中的一个内置函数,它基本上执行验证布尔语句的命令(如果您不知道那是什么,这就是您现在要在 if 语句中执行的操作:))
Another lazy way I found is :
我发现的另一种懒惰的方法是:
if any([x==0, y==0, z==0])
回答by B. M.
Set is the good approach here, because it orders the variables, what seems to be your goal here. {z,y,x}is {0,1,3}whatever the order of the parameters.
Set 是这里的好方法,因为它对变量进行排序,这似乎是您在这里的目标。{z,y,x}是{0,1,3}参数的任何命令。
>>> ["cdef"[i] for i in {z,x,y}]
['c', 'd', 'f']
This way, the whole solution is O(n).
这样,整个解决方案是 O(n)。
回答by michael zxc858
This code may be helpful
此代码可能会有所帮助
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;

