python filter rewrite filter
Question: Working code

    
    
    def not_double_cap_word(word):
        cap_count = 0
        for ch in word: 
            if str.isupper(ch):
                cap_count += 1
        not_double_cap = (cap_count < 2)
        return not_double_cap    
    ...
    
        words_no_double_caps =list(filter(not_double_cap_word,words_alnum))
    

What would be a different solution, say maybe using lambdas or other patterns
in Python? The above creates a new list of words with any word with more than
two caps removed. one two TWo => one, two.


Answer: You can definitely simplify that `not_double_cap_word` function, but it's
still going to be the same basic solution.

First, you can use `ch.isupper()` instead of `str.isupper(ch)`. Calling a
method the normal way is always easier than calling it as an unbound method
and passing the `self` explicitly.

Next, we can replace the explicit for loop with `sum` over a generator
expression:

    
    
    cap_count = sum(ch.isupper() for ch in word)
    

And we don't really need to define `not_double_cap`, `cap_count < 2` seems
simple enough to return directly. So:

    
    
    def not_double_cap_word(word):
        cap_count = sum(ch.isupper() for ch in word)
        return cap_count < 2
    

But really, this whole thing is probably simple enough to inline directly into
the main expression. While you _could_ do that by defining a function with
`lambda`, there's no reason to. In general, `map` and `filter` are good when
what you want to do to each thing is call a function that you already have
lying around; comprehensions are better when what you want to do is an
expression that you'd have to wrap in a function (`lambda` or otherwise) to
pass to `map` or `filter`. Compare:

    
    
    words_no_double_caps = [word for word in words_alnum 
                            if sum(ch.isupper() for ch in word) < 2]
    words_no_double_caps = list(filter((lambda word: sum(map(
                               lambda ch: ch.upper(), word)) < 2), words_alnum))
    

(I think I got the parens on the second version right. If not… well, if I
wanted to program in Lisp, I would.:)

Either way, it's performing pretty much the exact same steps as your original
code, but it's more concise. Is it more readable? That's for you to decide.
But that's the most important reason to choose one or the other, or something
intermediate between the two.

Well, that, and whether or not you need to reuse this logic; if you do, it
should _definitely_ be defined with a `def` statement and given a nice name.

