Подскажите, пожалуйста, как задать правильно такое условие в одной строке:
if (g%2=0 and g1%2=0 and v%2=0 and v1%2=0) or (g%2!=0 and g1%2!=0 and v%2!=0 and v1%2!=0):
На самом деле, я не рекомендую писать такое в одну строчку. Когда это будет читать другой программист (или вы сами через несколько месяцев), разбираться в таком коде будет сложно.
Лучше разбить сложное условие на несколько проверок.
Кроме того, почти всегда проверку числа на равенство нулю лучше заменить на использование самого числа как готового логического выражения.
Поскольку ноль эквивалентен False, а любое ненулевое число эквивалентно True,
num
можно использовать вместо num != 0
not num
можно использовать вместо num == 0
Длинный цепочки одинаковых операторов ‘and’ или ‘or’ лучше заменять на функции all() и any().
Таким образом, я бы рекомендовал вам переписать ваш код так:
check1 = not any([g % 2, g1 % 2, v % 2, v1 % 2]) check2 = all([g % 2, g1 % 2, v % 2, v1 %2]) if check1 or check2: # some code
Этот код можно ещё улучшить. Другие участники сообщества уже указали вам на то, что повторяющиеся вычисления можно вычислить один раз, и потом уже готовый результат использовать столько раз, сколько нужно.
В другой ситуации я бы то же посоветовал вам так сделать.
Но у вас всё ещё забавнее.
Поскольку остаток от деления на два может быть только либо 1, либо 0, а вы хотите проверить, что либо все четыре остатка равны нулю, либо все не равны, то ваше условие можно заменить таким:
if (g % 2) == (g1 % 2) == (v % 2) == (v1 % 2): # some code
Читается достаточно легко, и все остатки вычисляются только по одному разу.
Завести функцию с говорящим названием и её вызвать от аргументов.
def xor_like_function(*args): all_even = all(t%2 == 0 for t in args) all_odd = all(t%2 == 1 for t in args) return all_even or all_odd if xor_like_function(g, g1, v, v1): pass
Ещё неплохо подумать над хорошими именами для переменных g, g1, v, v1.
Чтобы записать условие в одной строке:
same_parity = (a & 1) == (b & 1) == (c & 1) == (d & 1) if same_parity: # ...
а ещё лучше использовать имя подходящее под вашу конкретную задачу, к примеру:
if can_access_foombulator: # ...
Ниже описано как ещё можно can_access_foombulator
вычислить.
Если вы видите в коде переменные типа g
, g1
, g2
, g3
, …, gn
, это значит что вместо этого вам можно использовать одно имя g
, ссылающуюся на всю коллекцию сразу. К примеру, вместо:
g, g1, g2 = 0, 1, 2
используйте:
g = 0, 1, 2
или
g = [0, 1, 2]
если вы хотите изменить g
позже. Аналогично для v
, v1
, etc.
Также, вероятно в вашем случае следует использовать более описательные имена чем g
, v
.
Таблица истинности для условия «all even» or «all odd» совпадает с XNOR:
A B XNOR 0 0 1 # all even 0 1 0 1 0 0 1 1 1 # all odd
для битов это совпадает с равенством, то есть:
can_access_foombulator = all_equal(*lsb) # all_equal = xnor
где LSB это Least Significant Bit:
lsb = [n & 1 for n in [g, g1, v, v1]]
и
def all_equal(*bits): return all(bits) or not any(bits)
Альтернативные реализации:
def all_equal(*items): return all(items[0] == x for x in items) def all_equal(*items): return items.count(items[0]) == len(items)
Проверяем четность первого элемента, дальше проверяем каждый следующий элемент на четность с предыдущим.
Если элементы по четности разные, возвращается False.
def all_even_or_odd(data): n = data[0]%2 for line in data: if line % 2 != n: return False return True numbers = [g, g1, v, v1] if all_even_or_odd(numbers): # Ваш код
Например так:
values = [g, g1, v, v1] if all(val%2==0 for val in values) or all(val%2!=0 for val in values):
Обратите внимание, что у вас в первом условии неверно проставлен оператор сравнения:
==
тк есть несколько проверок * % 2, чтобы не вычислять их для каждой проверки заново, можно сначала сохранить результат в res, а потом уже проверять
args = g, g1, v, v1 = 3, 3, 3, 3 check = lambda a: a % 2 res = list(map(check, args)) if all(res) or not any(res): print(True) # или так from functools import reduce if reduce(lambda x, y: bool(x % 2) is bool(y % 2), args): print(True) # или так if all(a % 2 for a in args) or not any(a % 2 for a in args): print(True)