List comprehension — приятная штука, позволяющая во многих ситуациях выразить мысль не только коротко, но и понятно. И всё же иногда кажется, что там чего-то не хватает. Вот несколько вариантов записи одного выражения:
[target for target in [long_expr_of(source) for source in sources]
if test_expr_of(target)]
filter(lambda x: test_expr_of(x),
[long_expr_of(source) for source in sources])
[long_expr_of(source) for source in sources
if test_expr_of(long_expr_of(source))]
Первый способ громоздок, да и читаются вложенные списки не так хорошо. Второй способ выглядит неплохо, только если есть готовая функция test_expr_of и нет необходимости писать lambda-выражение. Третий способ неприятен с точки зрения эффективности. В таких случаях я предпочитаю разбивать вычисление на два выражения:
targets = [long_expr_of(source) for source in sources]
targets = [target for target in targets if test_expr_of(target)]
Вроде всё замечательно и ничего больше не нужно. И всё-таки, вспоминая SQL, хочется записать что-то вроде:
[long_expr_of(source) as target for source in sources
if test_expr_of(target)]
Выглядит очень приятно. Может стоит написать PEP?