2017-08-16 12 views
1
>>> import functools 
>>> functools.reduce(lambda acc, val: acc + 1 if val == ' ' else 0, list("test test test"), 0) 
0 

は、私はちょうどので、私は(2つの空白があるので)ではない02を返す関数を期待テキスト内の空白をカウントします。reduceのラムダ式が期待どおりに動作しないのはなぜですか?

+7

は、 '(」「)' "テストテストテスト" .countと何が問題なのですか? – CoryKramer

+0

Pythonを学び、ちょうどPythonのlambdasに慣れたい。 –

+3

「else acc」にする必要があります。 – bereal

答えて

1

の式:

acc + 1 if val == ' ' else 0 

がそのように

(acc + 1) if val == ' ' else 0 

として解析され、アキュムレータは、それがスペース以外のものに遭遇するたびにリセットされます。だから、どちらかでなければなりません:

ちょうど
acc + 1 if val == ' ' else acc 

または

acc + (1 if val == ' ' else 0) 

かさえ:

acc + (val == ' ') 

しかし、当然のことながら、str.count()はそこに行くための方法です。

1

lambdaを簡単にデバッグするには、print() or (original lambda content)を使用します。これは、printが常にNoneを返すため、Pythonは常にorの後にその部分を実行するためです。あなたのケースにそれを適用する

:あなたはそれが空白ではない場合にはacc umulatorを保持しません。

0 t 
0 e 
0 s 
0 t 
0 
1 t 
0 e 
0 s 
0 t 
0 
1 t 
0 e 
0 s 
0 t 
0 

これは、何が悪かったのか説明します:印刷し

import functools 
functools.reduce(lambda acc, val: print(acc, val) or (acc + 1 if val == ' ' else 0), list("test test test"), 0) 

これを解決するにはいくつかの方法があります。私はprintをデバッグのために使用しますが、本当にそれらのどれかを使用したい場合はおそらくそれを削除するべきです。

一つは算術演算で使用される場合にブール値は整数のように振る舞うという事実を使用することであろう:それは空白に遭遇するたびにこれがアキュムレータに1(True)を追加

functools.reduce(lambda acc, val: print(acc, val) or (acc + (val == ' ')), list("test test test"), 0) 

をそれ以外の場合は0(False)を追加。

それともaccを維持するための自明な解:

functools.reduce(lambda acc, val: print(acc, val) or (acc + 1 if val == ' ' else acc), list("test test test"), 0) 

しかしreducelambdaを使用するよりも空白をカウントするためのより良い方法があります。たとえば:また、あなたのリストのために働く

"test test test".count(" ") 

list("test test test").count(" ") # but that's slower 

か:

from collections import Counter 
cnts = Counter("test test test") # counts all letters 
cnts[" "] 
関連する問題