views:

148

answers:

6

Is there a cleaner way to write this:

for w in [w for w in words if w != '']:

I want to loop over a dictionary words, but only words that != ''. Thanks!

+6  A: 

You don't need a listcomp here. Just write:

for w in words:
    if w != '':
        # ...
dan04
Alright. Worth a shot.
Jasie
Except List comprehension is the pythonic way of iterating....
Daniel Goldberg
@Daniel Goldberg, who said that, i thought 'for' was for iterating, and as OP is doing it it is overkill, @dan04 +1, that is the correct way...IMO
Anurag Uniyal
If you don't want to have another indentation level, you could always have `if w == "": continue` or `if not w: continue`, which is something I see pretty often.
Mike Graham
@Goldberg: Listcomps are preferred over loops that do .append to a list, not over loops in general.
dan04
+2  A: 

Assuming that you are after the keys, why not try:

[w for w in words if w]
inspectorG4dget
+1  A: 

filter(lambda w: w != '', words) or filter(None, words)

this is suggestion, it may not be the best solution for your problem.

aaa
"filter(P, S) is almost always written clearer as [x for x in S if P(x)]" - Guido van Rossum.
Noufal Ibrahim
@Nou I am partial towards functional stuff. at the same time guido really dislike them. they have their place, but probably not for OP problem
aaa
Your first snippet is a SyntaxError (I think you mean `!=`—`not` is something different). Using `filter` isn't somehow *more functional* than using a list comprehension (an idea we stole from no other but Haskell!), and using `filter` and `map` with lambdas seems downright silly to me.
Mike Graham
What do you mean by "functional stuff"? Do you mean the name `filter`? How is it semantically different from a list comprehension (which itself was borrowed from a pure functional language)?
Noufal Ibrahim
@Nou python manual calls them functional tools, hence functional stuff. sometimes I use them because they make code little bit cleaner in certain cases. semantically, that probably not different.
aaa
Why is this getting voted down? It may not suite some people's taste, but it's entirely valid.
allyourcode
+1 but only for `filter(None, words)`
kaizer.se
+1  A: 

Testing that an element does not equal '' isn't going to filter out whitespace elements. If that's what you're after, you probably want to use str.isspace (or a regular expression).

If you use a list comprehension, you'll make an extra copy of the list as an intermediary object. Probably not a big deal, but a generator won't use the extra memory.

I'd do it like this, with a generator:

for word in (w for w in words if not w.isspace()):
    # do stuff
Matt Anderson
A: 

What does the body of the outer for loop do?

If it's a function call you could potentially just do:

[f(w) for w in words if w != '']

Peter McGrattan
+1  A: 

I think your solution is sub optimal. You're iterating over the list words twice - once in the list comprehension to create the non-null terms and again in the loop to do the processing. It would be better if you used a genexp like so.

for w in (x for x in words if x): process(w)

That way, the genexp will lazily return a list of non-nulls.

Noufal Ibrahim
`for w in words: if x: process(w)` seems simpler, shorter, and clearer to me.
Mike Graham