如何使用函数式编程迭代并找到列表中五个连续数字的最大乘积?

ce1*_*ce1 13 python lambda functional-programming list

我必须使用函数式编程来实现以下函数,其中包含从0到9的数字列表.目标是找到列表中具有最大产品的五个连续元素.该函数应该返回最大乘积的索引的元组和最大乘积的值,而不使用max函数.

我可以在没有函数式编程的情况下轻松实现它,但是在没有任何循环的情 到目前为止,这是我的方法,但我坚持的部分是如何遍历数组以找到没有循环的连续五个数字.我正在尝试使用map来做到这一点,但我不认为这是正确的.是否有可能以任何方式合并枚举?任何帮助表示赞赏.

def find_products(L):
    val = map(lambda a: reduce(lambda x,y: x*y, L),L)
    print (val)
Run Code Online (Sandbox Code Playgroud)

Abh*_*kan 7

from functools import reduce #only for python3, python2 doesn't need import
def find_products(L):
    if len(L)==0:
        return 0
    if len(L) <= 5:
        return reduce( lambda x,y:x*y, L)
    pdts = ( reduce(lambda a,b:a*b,L[pos:pos+5]) for pos in range(len(L)-4)) # or pdts = map(lambda pos: reduce(lambda a,b:a*b,L[pos:pos+5],0),range(len(L)-4))
    mx = reduce(lambda x,y: x if x>y else y, pdts)
    return mx
Run Code Online (Sandbox Code Playgroud)

pdts包含所有可能的5元组产品,然后使用reduce模拟max功能,我们发现产品中的最大值.

  • @ comp.eng.函数式编程中的条件没有任何问题.Haskell有if,guard子句和模式匹配,所有形式的条件 - 没有条件就没有办法阻止递归. (5认同)

vau*_*tah 7

这没有任何显式循环或调用max函数.该函数假定输入列表中至少有五个元素并输出一个元组(start_index, max_product).

from functools import reduce, partial
import operator

def f(l):
    win = zip(l, l[1:], l[2:], l[3:], l[4:])
    products = map(partial(reduce, operator.mul), win)
    return reduce(lambda x, y: x if x[1] > y[1] else y, enumerate(products))
Run Code Online (Sandbox Code Playgroud)
In [2]: f([1, 2, 3, 4, 7, 8, 9])
Out[2]: (2, 6048)

In [3]: f([2, 6, 7, 9, 1, 4, 3, 5, 6, 1, 2, 4])
Out[3]: (1, 1512)
Run Code Online (Sandbox Code Playgroud)

win = zip(l, l[1:], l[2:], l[3:], l[4:])在输入列表上创建一个大小为5的滑动窗口迭代器.products = map(partial(reduce, operator.mul), win)是一个迭代器调用partial(reduce, operator.mul)(转换为reduce(operator.mul, ...))每个元素win.reduce(lambda x, y: x if x[1] > y[1] else y, enumerate(products))添加一个计数器products并返回具有最高值的索引值对.

如果您需要更通用的版本和/或输入列表很大,您可以使用itertools.islice:

from itertools import islice

def f(l, n=5):
    win = zip(*(islice(l, i, None) for i in range(n)))
    ...
Run Code Online (Sandbox Code Playgroud)

上面的代码在技术上使用了一个循环的生成器表达式.一个纯粹的功能版本可能看起来像

from itertools import islice

def f(l, n=5):
    win = zip(*map(lambda i: islice(l, i, None), range(n)))
    ...
Run Code Online (Sandbox Code Playgroud)

  • @EricDuminil是的,但如果列表很大`itertools.islice`应该是首选 (2认同)