本文翻译自:How to test multiple variables against a value?
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. 我想知道是否有办法将其转换为Python。 So say: 所以说:
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? 这样的事情可能吗?
#1楼
参考:https://stackoom.com/question/11PLx/如何针对一个值测试多个变量
#2楼
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:
x
and y
are otherwise evaluated on their own ( False
if 0
, True
otherwise). 否则将对x
和y
单独求值(如果为0
,则为False
,否则为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 set
to take advantage of the constant-cost membership test ( in
takes a fixed amount of time whatever the left-hand operand is). 使用一set
,以利用成本不变成员资格测试的( in
需要的固定时间量无论左边的操作数是)。
When you use or
, python sees each side of the operator as separate expressions. 当您使用or
,python会将运算符的每一面视为单独的表达式。 The expression x or y == 1
is treated as first a boolean test for x
, then if that is False, the expression y == 1
is tested. 表达式x or y == 1
首先被视为x
的布尔测试,然后如果它为False,则测试表达式y == 1
。
This is due to operator precedence . 这是由于运算符的优先级 。 The or
operator has a lower precedence than the ==
test, so the latter is evaluated first . or
运算符的优先级比==
测试低,因此首先评估后者。
However, even if this were not the case, and the expression x or y or z == 1
was actually interpreted as (x or y or z) == 1
instead, 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 z
would evaluate to the first argument that is 'truthy', eg not False
, numeric 0 or empty (see boolean expressions for details on what Python considers false in a boolean context). x or y or z
将求值为“真实”的第一个参数,例如,不为False
,数字0或为空(有关布尔值上下文中Python认为错误值的详细信息,请参见布尔值表达式 )。
So for the values x = 2; y = 1; z = 0
因此对于值x = 2; y = 1; z = 0
x = 2; y = 1; z = 0
x = 2; y = 1; z = 0
, x or y or z
would resolve to 2
, because that is the first true-like value in the arguments. x = 2; y = 1; z = 0
, x or y or z
将解析为2
,因为这是参数中的第一个真值。 Then 2 == 1
would be False
, even though y == 1
would be True
. 那么,即使y == 1
为True
, 2 == 1
也将为False
。
The same would apply to the inverse; 反之亦然; testing multiple values against a single variable; 针对单个变量测试多个值; x == 1 or 2 or 3
would fail for the same reasons. x == 1 or 2 or 3
会由于相同的原因而失败。 Use x == 1 or x == 2 or x == 3
or x in {1, 2, 3}
. x in {1, 2, 3}
使用x == 1 or x == 2 or x == 3
或x in {1, 2, 3}
。
#3楼
The direct way to write x or y or z == 0
is 写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 if
s could be written as something like this 顺便说一句, 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楼
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]]
#5楼
To check if a value is contained within a set of variables you can use the inbuilt modules itertools
and 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 itertools
to allow repetition of the variables: 使用itertools
允许重复变量:
check_vars = repeat((x, y, z))
Finally, use the map
function 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 operator
is an inbuilt module and is faster and more efficient than using lambda
which 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: 检查列表中是否存在非零(或False)值的另一个选项:
not (x and y and z)
Equivalent: 当量:
not all((x, y, z))
#6楼
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