2014-10-16 145 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']