for-if без понимания списка в одной строке - PullRequest
8 голосов
/ 19 ноября 2010

это можно записать в одну строку без списочных пониманий?

for x in vec: 
    if x > 3:
         ...
         ...

Ответы [ 5 ]

3 голосов
/ 19 ноября 2010

Смотрите @KennyTM ... нет причин так сильно сжимать.

Как говорится, for x in (i in vec if i > 3) выполняет свою работу, а также itertools.ifilter (или просто встроенный filter в Python 3) с предикатом lambda x: x > 3. Они также работают со всеми итерациями и ленивы (например, если вы break во время цикла, вы не слишком много проверяли ни одного элемента).

3 голосов
/ 19 ноября 2010

Нет, вы не можете . Справочник по языку Python гласит:

Составные операторы состоят из одного или нескольких «предложений».Предложение состоит из заголовка и «набора».Заголовки предложений конкретного составного оператора находятся на одном уровне отступа.Каждый заголовок предложения начинается с уникально идентифицирующего ключевого слова и заканчивается двоеточием.Комплект - это группа операторов, контролируемая предложением.Набор может состоять из одного или нескольких разделенных точкой с запятой простых операторов в той же строке, что и заголовок, после двоеточия заголовка, или это может быть один или несколько операторов с отступом в последующих строках. Только последняя форма набора может содержать вложенные составные операторы; следующее недопустимо, в основном потому, что неясно, к какому из условий относится следующее условие else:

if test1: if test2: print x

Действительно, Python генерирует SyntaxError для вложенных ifs выше.Более формально в отношении for, это его грамматика в Python:

for_stmt ::=  "for" target_list "in" expression_list ":" suite
              ["else" ":" suite]

suite         ::=  stmt_list NEWLINE | NEWLINE INDENT statement+ DEDENT

stmt_list     ::=  simple_stmt (";" simple_stmt)* [";"]

Обратите внимание, что когда после for следует оператор без отступа, этот оператор должен быть stmt_list, что позволяетsimple_stmt экземпляров.simple_stmt это:

simple_stmt ::=  expression_stmt
                 | assert_stmt
                 | assignment_stmt
                 | augmented_assignment_stmt
                 | pass_stmt
                 | del_stmt
                 | print_stmt
                 | return_stmt
                 | yield_stmt
                 | raise_stmt
                 | break_stmt
                 | continue_stmt
                 | import_stmt
                 | global_stmt
                 | exec_stmt

Который не включает составные операторы, такие как if и for.


При этом имейте в виду, что синтаксис Pythonнаправлены на ясность.Поэтому лучше не вкладывать такие утверждения, для этого были созданы генераторы / списки.Если вы считаете, что ваши вычисления достаточно просты для одной строки, то понимание для вас.В противном случае вы действительно не захотите загромождать код, располагая все в одной строке - аккуратно разбивайте его отступами.Несколько дополнительных линий в наши дни не стоят много.

0 голосов
/ 19 ноября 2010

Да

для x в фильтре (лямбда i: i> 3, vec):

0 голосов
/ 19 ноября 2010

Может, но списочные выражения / выражения генератора - это именно то, что нужно здесь использовать. В зависимости от того, что вы хотите сделать в своем блоке if, вы можете использовать некоторую форму map или reduce, но списочные выражения и выражения генератора, вероятно, лучший способ сделать это.

0 голосов
/ 19 ноября 2010

Вы можете представить себе нечто подобное:

def do_something(value):
    ...

def do_otherthing(value):
    ...


for x in t: do_something(x) if x>3 else do_otherthing(x)
...