python过滤器重写过滤器

时间:2014-10-16 18:27:27

标签: python list lambda

工作代码

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))

什么是不同的解决方案,比如可能在Python中使用lambdas或其他模式?上面创建了一个新的单词列表,其中包含删除了两个以上大写的任何单词。一两个TWo =&gt;一,二。

2 个答案:

答案 0 :(得分:2)

您绝对可以简化not_double_cap_word功能,但它仍然是相同的基本解决方案。

首先,您可以使用ch.isupper()代替str.isupper(ch)。以正常方式调用方法总是比将其作为未绑定方法调用并显式传递self更容易。

接下来,我们可以在生成器表达式上用sum替换显式for循环:

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

我们并不需要定义not_double_capcap_count < 2似乎很简单,可以直接返回。所以:

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

但实际上,这一切都很简单,可以直接内联到主表达式中。虽然你可以通过使用lambda定义一个函数来做到这一点,但是没有理由这样做。一般来说,mapfilter是好的,当你想对每件事情做的事情就是召唤你已经躺着的功能时;当你想要做的是一个你必须包裹在一个函数(lambda或其他)中传递给mapfilter的表达式时,理解会更好。比较:

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))

(我想我在第二个版本上得到了正确的答案。如果不是......好吧,如果我想用Lisp编程,我会。:)

无论哪种方式,它执行的步骤与原始代码完全相同,但它更简洁。它更具可读性吗?那是你决定的。但这是选择其中一个或两者之间的最重要原因。

那么,那你是否需要重用这个逻辑;如果你这样做,它应该明确def语句定义并给出一个好名字。

答案 1 :(得分:1)

您可以使用not_double_cap_word重写sum代码:

def not_double_cap_word(word):
    return sum(x.isupper() for x in word) < 2

如果您只是想要使用带过滤器的lambda而不使用not_double_cap_word函数:

print(list(filter(lambda x: sum(s.isupper() for s in x) < 2 ,["one", "two" ,"TWo"])))
['one', 'two']