协慌网

登录 贡献 社区

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

我正在尝试制作一个将多个变量与一个整数进行比较并输出三个字母的字符串的函数。我想知道是否有一种方法可以将其转换为 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"]

这样的事情可能吗?

答案

您误解了布尔表达式是如何工作的。它们不像英文句子那样工作,并且猜测您在这里谈论的是所有名称的相同比较。您正在寻找:

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

xy单独求值(如果为0False ,否则为True

您可以使用针对元组的容纳测试来缩短该时间:

if 1 in (x, y, z):

还是更好:

if 1 in {x, y, z}:

使用set来利用不变成本成员资格检验(即in无论左侧操作数是多少,都花费固定的时间)。

解释

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

这是由于运算符的优先级or运算符的优先级比==测试低,因此首先评估后者。

但是,即使不是这种情况,并且x or y or z == 1解释为(x or y or z) == 1 ,这仍然不会执行您期望的操作。

x or y or z将求值为 “真实” 的第一个参数,例如,不是False ,数字 0 或空(有关布尔值上下文中 Python 认为是 false 的详细信息, 请参见布尔值表达式)。

因此对于值x = 2; y = 1; z = 0x or y or z将解析为2 ,因为那是参数中的第一个真值。那么,即使y == 1True 2 == 1也将为False

反之亦然。针对单个变量测试多个值; x == 1 or 2 or 3会由于相同的原因而失败。 x in {1, 2, 3}使用x == 1 or x == 2 or x == 3或 x。

使用以下字典结构可以更轻松地解决您的问题:

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

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