什么是“pythonic”等价于函数式编程中的“fold”函数?

2024-03-28 20:04:16 发布

您现在位置:Python中文网/ 问答频道 /正文

在Haskell中,实现如下目标的最惯用方法是什么:

foldl (+) 0 [1,2,3,4,5]
--> 15

或红宝石中的等价物:

[1,2,3,4,5].inject(0) {|m,x| m + x}
#> 15

显然,Python提供了reduce函数,这是fold的一个实现,正如上面所述,但是,我被告知“pythonic”编程方法是避免lambda术语和更高阶函数,尽可能倾向于列表理解。因此,在Python中是否有一种折叠列表或类似列表的结构的首选方法不是reduce函数,或者reduce是实现这一点的惯用方法?


Tags: 方法lambda函数reduce目标列表haskell编程
3条回答

在Python 3中,reduce已被删除:Release notes。不过,您可以使用functools module

import operator, functools
def product(xs):
    return functools.reduce(operator.mul, xs, 1)

另一方面,文档表示倾向于for循环,而不是reduce,因此:

def product(xs):
    result = 1
    for i in xs:
        result *= i
    return result

对数组求和的python方法是使用^{}。出于其他目的,有时可以使用^{}(来自^{}模块)和^{}模块的组合,例如:

def product(xs):
    return reduce(operator.mul, xs, 1)

注意reduce实际上是一个foldl,用Haskell的术语来说。没有特殊的语法来执行折叠,没有内置的foldr,并且实际使用reduce与非关联运算符被认为是错误的风格。

使用高阶函数是非常Python的;它很好地利用了Python的原则,即一切都是对象,包括函数和类。你说得对,有些Python不喜欢羔羊,但主要是因为当它们变得复杂时,它们往往不太可读。

哈斯克尔

foldl (+) 0 [1,2,3,4,5]

Python

reduce(lambda a,b: a+b, [1,2,3,4,5], 0)

显然,这是一个简单的例子来说明一点。在Python中,您只需要做sum([1,2,3,4,5]),甚至Haskell纯粹主义者通常也会喜欢sum [1,2,3,4,5]

对于没有明显便利函数的非平凡场景,惯用的pythonic方法是显式地写出For循环并使用可变变量赋值,而不是使用reducefold

这根本不是功能性的风格,但这是“Python式”的方式。Python不是为功能纯粹主义者设计的。查看Python如何支持流控制的异常,以了解非功能的惯用Python是如何的。

相关问题 更多 >