a friend of mine suggested this, and i thought i should share it with the mailing list.<br>many times when you would want to use list/generator comprehensions, you have to<br>fall back to the old for/append way, because of exceptions. so it may be a good idea
<br>to allow an exception handling mechanism in these language constructs.<br><br>since list comprehensions are expressions, an exceptions thrown inside one means<br>the entire list is discarded. you may want to provide some, at least fundamental,
<br>error handling, like "if this item raises an exception, just ignore it", or "terminate the<br>loop in that case and return whatever you got so far".<br><br>the syntax is quite simple:<br><br>"[" <expr> for <expr> in <expr> [if <cond>] [except <exception-class-or-tuple>: <action>] "]"
<br><br>where <action> is be one of "continue" or "break":<br>* continue would mean "ignore this item"<br>* break would mean "return what you got so far"<br><br>for example:<br>
<br>a = ["i", "fart", "in", "your", "general", 5, "direction", "you", "silly", "english", "kniggits"]<br><br>give me every word that starts with "y", ignoring all errors
<br>b = [x for x in a if x.startswith("y") except: continue]<br># returns ["your", "you"]<br>
<br>or only AttributeError to be more speciifc<br>b = [x for x in a if x.startswith("y") except AttributeError: continue]<br># returns ["your", "you"]<br><br>and with break<br>
b = [x for x in a if x.startswith("y") except AttributeError: continue]<br>
# returns only ["your"] -- we didn't get past the 5<br>
<br>in order to do something like this today, you have to resort to the old way,<br>b = []<br>for x in a:<br> try:<br> if x.startswith("y"): <br> b.append(x)<br> except ...:<br> pass
<br><br>which really breaks the idea behind list comprehension. <br><br>so it's true that this example i provided can be done with a more complex if condition <br>(first doing hasattr), but it's not always possible, and how would you do it if the error
<br>occurs at the first part of the expression?<br><br>>>> y = [4, 3, 2, 1, 0, -1, -2, -3]<br>>>> [1.0 / x for x in y except ZeroDivisionError: break]<br>[0.25, 0.333, 0.5, 1.0]<br>>>> [1.0 / x for x in y except ZeroDivisionError: continue]
<br>[0.25, 0.333, 0.5, 1.0, -1.0, -0.5, -0.333]<br><br>again, in this example you can add "if x != 0", but it's not always possible to tell which<br>element will fail. for example:<br><br>filelist = ["a", "b", "c", "<\\/invalid file name:?*>", "e"]
<br>openfiles = [open(filename) for filename in filelist except IOError: continue]<br><br>the example is hypothetical, but in this case you can't tell *prior to the exception*<br>that the operation is invalid. the same goes for generator expressions, of course.
<br><br><br><br> -tomer