Рассмотрим следующий пример игрушки:
>>> def square(x): return x*x
...
>>> [square(x) for x in range(12) if square(x) > 50]
[64, 81, 100, 121]
Мне нужно дважды называть квадрат (x) в понимании списка. Дублирование является уродливым, подверженным ошибкам (легко изменить только один из двух вызовов при изменении кода) и неэффективно.
Конечно, я могу это сделать:
>>> squares = [square(x) for x in range(12)]
>>> [s for s in squares if s > 50]
[64, 81, 100, 121]
или это:
[s for s in [square(x) for x in range(12)] if s > 50]
Они оба пригодны для жизни, но кажется, что может быть способ сделать все это в одном заявлении, не вставляя два понимания списка, и я знаю, что мне придется долго смотреть на него в следующий раз, Чтение кода просто для выяснения того, что происходит. Есть ли способ?
Я думаю, что справедливый вопрос, чтобы спросить меня, будет таким, как я себе представляю, такой синтаксис мог бы выглядеть. Вот две идеи, но они не кажутся идиоматическими в Python (и они не работают). Они вдохновлены анафорическими макросами в Lisp.
[square(x) for x in range(12) if it > 50]
[it=square(x) for x in range(12) if it > 50]