Как протестировать несколько переменных на равенство одному значению?
Я пытаюсь создать функцию, которая будет сравнивать несколько переменных с целым числом и выводить строку из трех букв. Интересно, есть ли способ реализовать это на 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"]
Проблема в том, что в текущей реализации условия не работают так, как я ожидал. Мне не удается правильно сравнить все переменные x, y и z с числом. Помогите, пожалуйста, найти правильный способ сделать это. Как я могу переписать этот код, чтобы получить нужный результат?
5 ответ(ов)
Ваша проблема решается проще с использованием структуры словаря, например:
x = 0
y = 1
z = 3
d = {0: 'c', 1: 'd', 2: 'e', 3: 'f'}
mylist = [d[k] for k in [x, y, z]]
Таким образом, вы сможете извлечь значения по ключам из словаря d
и собрать их в список mylist
.
Как указал Мартейн Питерс, правильный и самый быстрый способ записи выглядит следующим образом:
if 1 in {x, y, z}:
Используя его совет, вы можете использовать отдельные условные операторы, что позволит 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")
...
Это сработает, но если вы комфортно себя чувствуете с использованием словарей (что я намекал), вы можете упростить этот код, создав начальный словарь, который сопоставляет числа с нужными буквами, а затем просто используя цикл 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])
Прямой способ записать x or y or z == 0
выглядит так:
if any(map((lambda value: value == 0), (x, y, z))):
pass # здесь ваша логика.
Но я не думаю, что вам это понравится. 😃 Этот способ выглядит не слишком красиво.
Лучший способ сделать это:
0 in (x, y, z)
Кстати, много if
можно записывать в подобном виде:
my_cases = {
0: lambda: Mylist.append("c"),
1: lambda: Mylist.append("d")
# ..
}
for key in my_cases:
if key in (x, y, z):
my_cases[key]() # вызываем соответствующую лямбду
break
Таким образом, вы можете избежать повторяющегося кода и сделать его более читаемым.
Чтобы проверить, содержится ли значение в наборе переменных, вы можете использовать встроенные модули itertools
и operator
.
Например:
Импорты:
from itertools import repeat
from operator import contains
Объявите переменные:
x = 0
y = 1
z = 3
Создайте сопоставление значений (в том порядке, в котором вы хотите проверить):
check_values = (0, 1, 3)
Используйте itertools
, чтобы разрешить повторение переменных:
check_vars = repeat((x, y, z))
Наконец, используйте функцию map
, чтобы создать итератор:
checker = map(contains, check_vars, check_values)
Теперь при проверке значений (в исходном порядке) используйте next()
:
if next(checker): # Проверяет для 0
# Действие при выполнении условия
pass
elif next(checker): # Проверяет для 1
# Действие при выполнении условия
pass
и так далее...
Этот подход имеет преимущество перед lambda x: x in (variables)
, потому что operator
является встроенным модулем и работает быстрее и эффективнее, чем использование lambda
, которому необходимо создавать пользовательскую функцию на месте.
Другой вариант для проверки, есть ли ненулевое (или False) значение в списке:
not (x and y and z)
Эквивалентно:
not all((x, y, z))
Если вы ОЧЕНЬ ленивы, вы можете поместить значения в массив. Например:
list = []
list.append(x)
list.append(y)
list.append(z)
nums = [вставьте числа сюда]
letters = [вставьте соответствующие буквы сюда]
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])
Почему сравнение строк с помощью '==' и 'is' иногда дает разные результаты?
Однострочное выражение if-then-else
Стилизация многострочных условий в операторе 'if'? [закрыто]
Какой эквивалент инструкции case/switch в Python?
Как выполнить регистронезависимое сравнение строк?