Как проверить несколько переменных на соответствие значению

python if-statement comparison match boolean-logic


Я пытаюсь сделать функцию,которая будет сравнивать несколько переменных с целым числом и выводить строку из трех букв.Мне интересно,есть ли способ перевести это на 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"]

Возможно ли что-то подобное?





Answer 1 Martijn Pieters


Вы неправильно понимаете,как работают булевы выражения;они не работают как английское предложение,и догадываетесь,что здесь речь идет об одном и том же сравнении для всех имён.Вы ищете:

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

x и y в противном случае оцениваются самостоятельно ( False , если 0 , 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 = 0 у = 1; z = 0 , x or y or z будут преобразованы в 2 , потому что это первое истинное значение в аргументах. Тогда 2 == 1 будет False , хотя y == 1 будет True .

То же самое относится к обратному; тестирование нескольких значений по одной переменной; x == 1 or 2 or 3 потерпит неудачу по тем же причинам. Используйте x == 1 or x == 2 or x == 3 или x in {1, 2, 3} .




Answer 2 dansalmo


Вашу проблему легче решить с помощью такой словарной структуры,как словарь:

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



Answer 3 ThatGuyRussell


Как заявил Мартин Питерс,правильным и самым быстрым является формат:

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



Answer 4 akaRem


Прямой способ написать x or y or z == 0

if any(map((lambda value: value == 0), (x,y,z))):
    pass # write your logic.

Но я не думаю,что тебе это нравится.:)И этот путь уродлив.

Другой путь (лучше):

0 in (x, y, z)

Кстати много 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



Answer 5 ytpillai


Если вы очень ленивы,вы можете поместить значения внутри массива.Например

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 x or y or z == 0:

составят,но не так,как ты хочешь.Когда вы просто помещаете переменную в оператор if (пример)

if b

программа проверит,не является ли переменная нулевой.Другой способ записать приведенное выше утверждение (что имеет больший смысл)-это

if bool(b)

Bool-это встроенная функция в питоне,которая,по сути,выполняет команду проверки булевого оператора (если вы не знаете,что это такое,то это то,что вы пытаетесь сделать в вашем if операторе прямо сейчас :)).

Еще один ленивый способ,который я нашел:

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