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

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

我正在尝试编写一个函数,将多个变量与一个整数进行比较,并输出一个由三个字母组成的字符串。我想知道有没有办法把它翻译成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"]
mnemlml8

mnemlml81#

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

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}

qyuhtwio

qyuhtwio2#

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

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

falq053o3#

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

qoefvg9y4#

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
pdtvr36n

pdtvr36n5#

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 :)

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 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 :))

Another lazy way I found is :

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

vxf3dgd46#

To check if a value is contained within a set of variables you can use the inbuilt modules itertools and 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:

check_vars = repeat((x, y, z))

Finally, use the map function to create an iterator:

checker = map(contains, check_vars, check_values)

Then, when checking for the values (in the original order), use 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.

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))
ig9co6j1

ig9co6j17#

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.

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

This way, the whole solution is O(n).

gcxthw6b

gcxthw6b8#

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
tvmytwxo

tvmytwxo9#

If you want to use if, else statements following is another solution:

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)
2uluyalo

2uluyalo10#

All of the excellent answers provided here concentrate on the specific requirement of the original poster and concentrate on the if 1 in {x,y,z} solution put forward by Martijn Pieters.
What they ignore is the broader implication of the question:

How do I test one variable against multiple values?

The solution provided will not work for partial hits if using strings for example:
Test if the string "Wild" is in multiple values

>>> x = "Wild things"
>>> y = "throttle it back"
>>> z = "in the beginning"
>>> if "Wild" in {x, y, z}: print (True)
...

or

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

for this scenario it's easiest to convert to a 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

It should be noted however, as mentioned by @codeforester, that word boundries are lost with this method, as in:

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

the 3 letters rot do exist in combination in the list but not as an individual word. Testing for " rot " would fail but if one of the list items were "rot in hell", that would fail as well.
The upshot being, be careful with your search criteria if using this method and be aware that it does have this limitation.

6rqinv9w

6rqinv9w11#

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

ve7v8dk212#

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

qyzbxkaa13#

You can try the method shown below. In this method, you will have the freedom to specify/input the number of variables that you wish to enter.

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

fcwjkofz14#

One line solution:

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

Or:

mylist = ['cdef'[i] for i in range(4) if i in (x, y, z)]
chhqkbe1

chhqkbe115#

Maybe you need direct formula for output bits set.

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

Let's map to bits: 'c':1 'd':0xb10 'e':0xb100 'f':0xb1000

Relation of isc (is 'c'):

if xyz=0 then isc=1 else isc=0

Use math if formula 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))

...

Connect these formulas by following logic:

  • logic and is the sum of squares of equations
  • logic or is the product of equations

and you'll have a total equation express sum and you have total formula of sum

then sum&1 is c, sum&2 is d, sum&4 is e, sum&5 is f

After this you may form predefined array where index of string elements would correspond to ready string.

array[sum] gives you the string.

相关问题