Ответ 1
Просто складывайте их друг за другом:
[i for i in range(100) if i > 10 if i < 50]
Производит целые числа от 11 до 49 включительно.
Мы все знаем python
[f(x) for x in y if g(x)]
синтаксис.
Однако AST представление понимания списка имеет место для более чем одного выражения 'if':
comprehension = (expr target, expr iter, expr* ifs)
Может ли кто-нибудь дать мне пример кода на языке python, который будет генерировать AST с более чем одним выражением "if"?
Просто складывайте их друг за другом:
[i for i in range(100) if i > 10 if i < 50]
Производит целые числа от 11 до 49 включительно.
Грамматика допускает несколько операторов if, потому что вы можете смешивать их между циклами for:
[j for i in range(100) if i > 10 for j in range(i) if j < 20]
Компоненты понимания должны рассматриваться как вложенные операторы, приведенные выше:
lst = []
for i in range(100):
if i > 10:
for j in range(i):
if j < 20:
lst.append(j)
Это также означает, что вы можете использовать несколько операторов if
без циклов for
между:
[i for i in range(100) if i > 10 if i < 20]
Несмотря на нечувствительность (просто объедините те, которые используют and
или с цепочками операторов), он еще раз переводит в законный вложенный набор операторов:
lst = []
for i in range(100):
if i > 10:
if i < 20:
lst.append(i)
Грамматика и парсер специально не запрещают такое использование, так же, как Python не запрещает вам вставлять инструкции if
.
ссылка на язык дает лучшее представление об этом:
list_comprehension ::= expression list_for
list_for ::= "for" target_list "in" old_expression_list [list_iter]
list_iter ::= list_for | list_if
list_if ::= "if" old_expression [list_iter]
Как вы видите, понимание списка определяется с опциональным list_iter
в конце - одним list_iter
. Теперь этот list_iter
может быть либо другой частью понимания списка, либо условием if. Само условие if заканчивается еще одним необязательным list_iter
. Это необходимо для обеспечения возможности объединения нескольких частей с дополнительными if-условиями в одно и то же понимание списка. Тот факт, что вы могли бы также построить часть .. if X if Y if Z
для list_iter
, является лишь побочным эффектом.
Таким образом, хотя возможность связывать только несколько if-условий не требуется, она позволяет определить всю грамматику таким образом.
Использование встроенного all()
позволяет размещать несколько логических выражений или функций в итерабельном и придерживаться вашего понимания. Я думаю, что это довольно при использовании встроенного, и он обеспечивает читаемость высокой.
>>> [x for x in range(20) if all([1 < x < 10, not x & 1])]
[2, 4, 6, 8]
или
>>> [x for x in range(20) if all([foo(x), bar(x)])]
построенный any()
также будет работать здесь, если нужно выполнить только одно условие:
>>> [x for x in range(20) if any([1 < x < 10, not x & 1])]
[0, 2, 3, 4, 5, 6, 7, 8, 9, 10, 12, 14, 16, 18]
Попробуйте использовать следующий код:
>>> [i for i in range(50) if i in range(10,20)]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
который дает исчерпывающий результат.