Понимание python-списка с несколькими "if's - программирование
Подтвердить что ты не робот

Понимание python-списка с несколькими "if's

Мы все знаем python

[f(x) for x in y if g(x)]

синтаксис.

Однако AST представление понимания списка имеет место для более чем одного выражения 'if':

comprehension = (expr target, expr iter, expr* ifs)

Может ли кто-нибудь дать мне пример кода на языке python, который будет генерировать AST с более чем одним выражением "if"?

4b9b3361

Ответ 1

Просто складывайте их друг за другом:

[i for i in range(100) if i > 10 if i < 50]

Производит целые числа от 11 до 49 включительно.

Ответ 2

Грамматика допускает несколько операторов 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.

Ответ 3

ссылка на язык дает лучшее представление об этом:

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-условий не требуется, она позволяет определить всю грамматику таким образом.

Ответ 4

Использование встроенного 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]

Ответ 5

Попробуйте использовать следующий код:

>>> [i for i in range(50) if i in range(10,20)]
[10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

который дает исчерпывающий результат.