The Python Oracle

What is the 'pythonic' equivalent to the 'fold' function from functional programming?

Become part of the top 3% of the developers by applying to Toptal https://topt.al/25cXVn

--

Music by Eric Matyas
https://www.soundimage.org
Track title: Flying Over Ancient Lands

--

Chapters
00:00 Question
00:57 Accepted answer (Score 158)
01:59 Answer 2 (Score 65)
03:06 Answer 3 (Score 22)
04:14 Answer 4 (Score 14)
04:43 Thank you

--

Full question
https://stackoverflow.com/questions/1036...

Accepted answer links:
[sum]: https://docs.python.org/3/library/functi...
[reduce]: https://docs.python.org/3/library/functo...
[functools]: https://docs.python.org/3/howto/function...
[operator]: https://docs.python.org/3/library/operat...

Answer 2 links:
[assignment expressions (PEP 572)]: https://www.python.org/dev/peps/pep-0572/

Answer 4 links:
[Release notes]: https://docs.python.org/3.0/whatsnew/3.0...
[functools module]: https://docs.python.org/3/howto/function...

--

Content licensed under CC BY-SA
https://meta.stackexchange.com/help/lice...

--

Tags
#python #list #functionalprogramming #reduce #fold

#avk47



ANSWER 1

Score 162


The Pythonic way of summing an array is using sum. For other purposes, you can sometimes use some combination of reduce (from the functools module) and the operator module, e.g.:

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

Be aware that reduce is actually a foldl, in Haskell terms. There is no special syntax to perform folds, there's no builtin foldr, and actually using reduce with non-associative operators is considered bad style.

Using higher-order functions is quite pythonic; it makes good use of Python's principle that everything is an object, including functions and classes. You are right that lambdas are frowned upon by some Pythonistas, but mostly because they tend not to be very readable when they get complex.




ANSWER 2

Score 26


Haskell

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

Python

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

Obviously, that is a trivial example to illustrate a point. In Python you would just do sum([1,2,3,4,5]) and even Haskell purists would generally prefer sum [1,2,3,4,5].

For non-trivial scenarios when there is no obvious convenience function, the idiomatic pythonic approach is to explicitly write out the for loop and use mutable variable assignment instead of using reduce or a fold.

That is not at all the functional style, but that is the "pythonic" way. Python is not designed for functional purists. See how Python favors exceptions for flow control to see how non-functional idiomatic python is.




ANSWER 3

Score 17


In Python 3, the reduce has been removed: Release notes. Nevertheless you can use the functools module

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

On the other hand, the documentation expresses preference towards for-loop instead of reduce, hence:

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



ANSWER 4

Score 9


Not really answer to the question, but one-liners for foldl and foldr:

a = [8,3,4]

## Foldl
reduce(lambda x,y: x**y, a)
#68719476736

## Foldr
reduce(lambda x,y: y**x, a[::-1])
#14134776518227074636666380005943348126619871175004951664972849610340958208L