如何针对单个值测试多个变量的相等性?

daupos2t  于 2022-09-18  发布在  Java
关注(0)|答案(30)|浏览(168)

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:

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"]
at0kjp5o

at0kjp5o16#

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

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

xy以其他方式单独计算(如果是0,则为False,否则为True)。

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

if 1 in (x, y, z):

或者更好的是:

if 1 in {x, y, z}:

使用set来利用不变成本成员关系测试(即,无论左操作数是什么,in都需要固定的时间)。

说明

当您使用or时,Python将运算符的每一端视为单独的表达式。表达式x or y == 1首先被视为对x的布尔测试,如果为假,则对表达式y == 1进行测试。

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

然而,即使情况并非如此,表达式x or y or z == 1实际上被解释为(x or y or z) == 1,这仍然不会达到您预期的效果。

x or y or z将计算为第一个‘true’参数,例如,不是False、数字0或空(有关在布尔上下文中,Python认为是假的详细信息,请参阅布尔表达式)。

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

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

vwhgwdsa

vwhgwdsa17#

也许您需要输出位集的直接公式。

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

让我们Map到位:'c':1 'd':0xb10 'e':0xb100 'f':0xb1000

ISC的关系(is‘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]为您提供字符串。

wvyml7n5

wvyml7n518#

单行解决方案:

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

fiei3ece19#

您可以尝试下面所示的方法。在这种方法中,您可以自由地指定/输入您希望输入的变量数量。

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

vatpfxk520#

此代码可能会有所帮助

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

a6b3iqyw21#

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

rm5edbpk22#

这里提供的所有优秀答案都集中在原始海报的具体要求上,集中在马提金·皮特斯提出的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所提到的,使用这种方法会丢失单词boundries,例如:

>>> x=['Wild things', 'throttle it back', 'in the beginning']
>>> if "rot" in str(x): print(True)
... 
True

这3个字母rot确实组合在列表中,但不是作为一个单独的单词。测试“烂”将会失败,但如果列表中的某一项“烂在地狱”,那也将失败。
结果是,如果使用此方法,请注意您的搜索条件,并意识到它确实有此限制。

t3psigkw

t3psigkw23#

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

eqfvzcg824#

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

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
qv7cva1a

qv7cva1a25#

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

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

这样,整个解就是O(N)。

oug3syen

oug3syen26#

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

例如:

进口:

from itertools import repeat
from operator import contains

声明变量:

x = 0
y = 1
z = 3

创建值的Map(按您要检查的顺序):

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更快、更高效,lambda必须创建自定义就地函数。

用于检查列表中是否存在非零(或假)值的另一个选项:

not (x and y and z)

等价物:

not all((x, y, z))
5rgfhyps

5rgfhyps27#

如果您非常非常懒惰,可以将这些值放入数组中。比如

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语句复杂得多。这就是你试图变得格外懒惰所得到的:)

还有一件事,你的

if x or y or z == 0:

将进行编译,但不是以您希望的方式进行编译。当您只需在if语句中放入一个变量时(示例)

if b

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

if bool(b)

Bool是Python中的一个内置函数,它基本上执行验证布尔语句的命令(如果您不知道这是什么,它就是您现在试图在if语句中创建的:)

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

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

wqnecbli28#

The direct way to write x or y or z == 0 is

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

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

7jmck4yq29#

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

if 1 in {x, y, z}:

按照他的建议,您现在可以使用单独的if-语句,这样,无论前者是True还是False,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")
...

这是可行的,但如果您习惯于使用字典(参见我在那里所做的),您可以通过创建一个将数字Map到您想要的字母的初始字典,然后只需使用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])
sshcrbum

sshcrbum30#

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

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

相关问题