
On Wed, Aug 27, 2008 at 9:51 AM, Tarek Ziadé <ziade.tarek@gmail.com> wrote:
Hello
There's a pattern I am doing all the time: filtering out some elements of a list, and cleaning them in the same move.
For example, if I have a multi line text, where I want to:
- keep non empty lines - clean non empty lines
I am doing:
>>> text = """ ... this is a multi-line text\t ... ... \t\twith ... ... muliple lines."""
>>> [l.strip() for l in text.split('\n') if l.strip() != ''] ['this is a multi-line text', 'with', 'muliple lines.']
It is not optimal, because I call strip() twice. I could use ifilter then imap or even use a real loop, but I want my simple, concise, list comprehension ! And I couldn't find a simple way to express it.
The pattern can be generically resumed like this :
[transform(e) for e in seq if some_test(transform(e))]
So what about using the 'as' keyword to extend lists comprehensions, and to avoid calling transform() twice ?
Not worth it since while you might want your "simple. concise list comprehension", listcomps are not meant to generalize for all possible situations in 'for' loops that can lead to a new list. Is it really that much harder to write:: list_ = [] for line in text.splitlines(): line = line.strip(): if line: list_.append(line) ? And if you really want your one-liner, you can avoid your duplicate call to str.strip() in two different ways:: [line.strip() for line in text.splitlines() if line and not line.isspace()] or:: filter(None, (line.strip() for line in text.splitlines())) I don't see enough benefit to clutter listcomps with more syntax and to provide another alternative to this pattern to add to the multiple ones that already exist. -Brett