Очевидное назначение моржового оператора - сократить количество кода. Сделать присвоение значения переменной и его использование в одно действие. Чаще всего используется в конструкциях
if и whileif match := pattern.search(data):
print(match.groups())
while chunk := file.read(1024):
process(chunk)
Можно ли использовать его внутри
f-string?print(f'{x:=10}')
# NameError: name 'x' is not definedЭто синтаксис форматирования а не walrus. Чтобы превратить выражение в walrus используем скобки
print(f'{(x:=15)}')
# '15'
print(x)
# 15Получается, что скобки помогут использовать walrus не только с
if, while, match и тд.Пример не самого очевидного присвоения значений переменным
x = (y := 1, 2)
print(x)
print(y)
# (1, 2)
# 1
Вызов функции тоже может быть использован как скобки для walrus
def get(): return 2
def do_it(x, y): return x + y
x = do_it(y := get(), y+3)
print(x, y)
# 7 2
Два "моржа"
def compute(x): return x*2
def get_value(): return 1
if z := compute(x := get_value()):
print(f"compute({x}) = {z}")
else:
print(f"{x} is not valid value")
# compute(1) = 2
В следующем примере мы экономим не только код но и количество расчётов
list1 = [1, 2, 3, 4, 5]
# без walrus
list2 = [x*2 for x in list1 if x*2 % 15 == 0]
# c walrus
list2 = [(n := x*2) for x in list1 if n % 15 == 0]
Создание списка выполняется последовательно, поэтому можно объявить переменную в первом элементе и использовать в остальных
f = lambda v: v*2
[y := f(1), y**2, y**3]
# [2, 4, 8]
Более страшный пример с созданием
lambda через walrus[y := (f := lambda x, i: x*i)(3, 10), z:=f(y, 20), f(z, 30)]
# [30, 600, 18000]
не делайте так
Экономим один вызов
lower() в простом выраженииis_palindrome = (w := word.lower()) == w[::-1]
И ещё пример экономии места в файле и времени CPU
try:
10 / 0
except Exception as err:
logger.log(message := f"Error, {err}!")
send_report(message)
А еще не будет ошибкой синтаксиса если использовать walrus перед
return. def calculate(a, b):
return result := a * b
Но, по очевидным причинам, смысла в этом нет 😄
#triks