【问题标题】:Why is my lambda expression for reduce not working as expected?为什么我的 reduce 的 lambda 表达式没有按预期工作?
【发布时间】:2018-01-24 15:01:33
【问题描述】:
>>> import functools
>>> functools.reduce(lambda acc, val: acc + 1 if val == ' ' else 0, list("test test test"), 0)
0

我只想计算文本中的空格,所以我希望函数返回2(因为有两个空格)而不是0

【问题讨论】:

  • "test test test".count(" ") 有什么问题?
  • 学习python,只是想习惯python的lambdas。
  • 应该是else acc
  • 如果您只是想熟悉lambdas,那么将它与reduce 一起使用会模糊问题...也许在mapfilter 中使用它们来让它专注于 lambda,而不是 reduce 工作方式的细微差别。
  • @bereal,非常感谢我的朋友,它正在工作!我花了太多时间,把我的脑袋弄坏了!原来如此简单。

标签: python lambda reduce counting


【解决方案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() 是去那里的方式。

【讨论】:

    【解决方案2】:

    调试lambdas 的一种简单方法是使用print() or (original lambda content)。这是因为print 总是返回None,因此Python 总是会执行or 之后的部分。

    将其应用于您的案例:

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

    哪个打印:

    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
    

    这解释了哪里出了问题:你不要保留accumulator,以防它不是空格。

    有几种方法可以解决此问题。出于调试原因,我将保留print,但如果您真的想使用其中任何一个,您可能应该删除它。

    如果在算术运算中使用布尔值,则其行为类似于整数:

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

    每当遇到空格时,这会将 1 (True) 添加到累加器,否则会添加 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[" "]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-02-29
      • 2021-11-11
      • 1970-01-01
      相关资源
      最近更新 更多