>>> import functools
>>> functools.reduce(lambda acc, val: acc + 1 if val == ' ' else 0, list("test test test"), 0)
0
は、私はちょうどので、私は(2つの空白があるので)ではない0
2
を返す関数を期待テキスト内の空白をカウントします。reduceのラムダ式が期待どおりに動作しないのはなぜですか?
>>> import functools
>>> functools.reduce(lambda acc, val: acc + 1 if val == ' ' else 0, list("test test test"), 0)
0
は、私はちょうどので、私は(2つの空白があるので)ではない0
2
を返す関数を期待テキスト内の空白をカウントします。reduceのラムダ式が期待どおりに動作しないのはなぜですか?
の式:
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()
はそこに行くための方法です。
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)
しかしreduce
とlambda
を使用するよりも空白をカウントするためのより良い方法があります。たとえば:また、あなたのリストのために働く
"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[" "]
は、 '(」「)' "テストテストテスト" .countと何が問題なのですか? – CoryKramer
Pythonを学び、ちょうどPythonのlambdasに慣れたい。 –
「else acc」にする必要があります。 – bereal