Erweiterte "For"-Schleife

09/05/2012 - 14:23 von ole-usenet-spam | Report spam
Hallo Gruppe,

In einer List comprehension funktioniert ja folgendes:

mynewlist = [ foo(item) for item in myoldlist if bar(item) ]

Wenn man die Schleife aufdröseln will, geht das leider nicht so einfach:

mynewlist = []
for item in myoldlist:
if bar(item):
mynewlist.append(foo(item))

Warum geht hier nicht folgendes?

for item in myoldlist if bar(item):
mynewlist.append(foo(item))

(Schon klar: weil es die Syntax nicht zulàsst. Aber warum wurde das so
designed?)

Cheers

Ole
 

Lesen sie die antworten

#1 Thomas Rachel
09/05/2012 - 15:00 | Warnen spam
Am 09.05.2012 14:23 schrieb Olе Streicher:
Hallo Gruppe,

In einer List comprehension funktioniert ja folgendes:

mynewlist = [ foo(item) for item in myoldlist if bar(item) ]



In einer Generator expression auch...

Wenn man die Schleife aufdröseln will, geht das leider nicht so einfach:

mynewlist = []
for item in myoldlist:
if bar(item):
mynewlist.append(foo(item))

Warum geht hier nicht folgendes?

for item in myoldlist if bar(item):
mynewlist.append(foo(item))



Schwer zu sagen. Mir hat es auch schon gefehlt. Aber - auch wen die
beiden gleich aussehen -: ich nehme an, daß die verschiedenen
for-Inkarnationen grammatikalisch nicht viel miteinander zu tun haben.

Auf der einen Seite gibt es

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

, desweiteren für List Comprehensions

list_display ::= "[" [expression_list | list_comprehension] "]"
list_comprehension ::= expression list_for
list_for ::= "for" target_list "in" old_expression_list
[list_iter]
old_expression_list ::= old_expression [("," old_expression)+ [","]]
old_expression ::= or_test | old_lambda_form
list_iter ::= list_for | list_if
list_if ::= "if" old_expression [list_iter]

comprehension ::= expression comp_for
comp_for ::= "for" target_list "in" or_test [comp_iter]
comp_iter ::= comp_for | comp_if
comp_if ::= "if" expression_nocond [comp_iter]

Und vermutlich ist es im Parser/Lexer (wer auch immer dafür zustàndig
ist, kenne mich da nicht so aus...) daher auch an unterschiedlichen
Stellen implementiert.

Schöner wàre sicherlich einfach ein

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

- das würde auch verschachtelte Shleifen vereinfachen.

Ansonsten muß man sich eben mit

for item in (item for item in myoldlist if bar(item)):
...

behelfen.

BTW: In Deinem Fall ginge auch ein Einzeiler:

mynewlist.extend(foo(item) for for item in myoldlist if bar(item))


HTH,

Thomas

Ähnliche fragen