2014-10-16 149 views
0

工作代码蟒蛇过滤器重写过滤

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

这将是一个不同的解决方案,说也许使用lambda表达式或其他图案在Python?上面创建了一个新的单词列表,其中任何单词的两个以上的大写删除。一两两=>一,二。

+0

我不跟着你的输出“一个两个”如何成为“一个,两个”。 – 2014-10-16 18:34:06

+0

你是什么意思“使用lambdas”? 'lambda'只是一种不同的写'def'给你的函数的方法,它不允许你使用语句或给函数一个名字,但是允许你在函数的中间表达。你为什么想要这样? – abarnert 2014-10-16 18:35:28

回答

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语句并给出一个不错的名字。

+0

lambda word:sum(ch.isupper()for ch in word)<2,使用理解而不是过滤器更简单。我想看看lambda看看如果复杂与理解。 – Paul 2014-10-16 20:43:41

+0

@保罗:好的,我可以编辑它以使其更清晰。 – abarnert 2014-10-16 21:28:03

1

可以使用sum重写not_double_cap_word代码:

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

如果你只是想TI使用lambda带有过滤器,而不是使用not_double_cap_word功能:

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