[Python-Dev] suggestion: except in list comprehension (original) (raw)
tomer filiba tomerfiliba at gmail.com
Mon Apr 24 22:56:37 CEST 2006
- Previous message: [Python-Dev] Must objects with __enter__/__exit__ also supply __context__?
- Next message: [Python-Dev] suggestion: except in list comprehension
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
a friend of mine suggested this, and i thought i should share it with the mailing list. many times when you would want to use list/generator comprehensions, you have to fall back to the old for/append way, because of exceptions. so it may be a good idea to allow an exception handling mechanism in these language constructs.
since list comprehensions are expressions, an exceptions thrown inside one means the entire list is discarded. you may want to provide some, at least fundamental, error handling, like "if this item raises an exception, just ignore it", or "terminate the loop in that case and return whatever you got so far".
the syntax is quite simple:
"[" for in [if ] [except : ] "]"
where is be one of "continue" or "break":
- continue would mean "ignore this item"
- break would mean "return what you got so far"
for example:
a = ["i", "fart", "in", "your", "general", 5, "direction", "you", "silly", "english", "kniggits"]
give me every word that starts with "y", ignoring all errors b = [x for x in a if x.startswith("y") except: continue]
returns ["your", "you"]
or only AttributeError to be more speciifc b = [x for x in a if x.startswith("y") except AttributeError: continue]
returns ["your", "you"]
and with break b = [x for x in a if x.startswith("y") except AttributeError: continue]
returns only ["your"] -- we didn't get past the 5
in order to do something like this today, you have to resort to the old way, b = [] for x in a: try: if x.startswith("y"): b.append(x) except ...: pass
which really breaks the idea behind list comprehension.
so it's true that this example i provided can be done with a more complex if condition (first doing hasattr), but it's not always possible, and how would you do it if the error occurs at the first part of the expression?
y = [4, 3, 2, 1, 0, -1, -2, -3] [1.0 / x for x in y except ZeroDivisionError: break] [0.25, 0.333, 0.5, 1.0] [1.0 / x for x in y except ZeroDivisionError: continue] [0.25, 0.333, 0.5, 1.0, -1.0, -0.5, -0.333]
again, in this example you can add "if x != 0", but it's not always possible to tell which element will fail. for example:
filelist = ["a", "b", "c", "<\/invalid file name:?*>", "e"] openfiles = [open(filename) for filename in filelist except IOError: continue]
the example is hypothetical, but in this case you can't tell prior to the exception that the operation is invalid. the same goes for generator expressions, of course.
-tomer -------------- next part -------------- An HTML attachment was scrubbed... URL: http://mail.python.org/pipermail/python-dev/attachments/20060424/c3635932/attachment.htm
- Previous message: [Python-Dev] Must objects with __enter__/__exit__ also supply __context__?
- Next message: [Python-Dev] suggestion: except in list comprehension
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]