gpt4 book ai didi

Python中递归减少的Pythonic方法

转载 作者:行者123 更新时间:2023-11-30 22:17:00 24 4
gpt4 key购买 nike

在 python 中减少列表时,我考虑过创建多个列表减少并编写了以下代码片段。

def multiply(a, b): return a * b

def recursive_reduce(reduce_func, *args):
ret_val = reduce(reduce_func, *args)
if type(ret_val) == list:
ret_val = recursive_reduce(reduce_func, ret_val)
return ret_val

a = [1, 1, 3]
b = [4, 5, 6]

recursive_reduce(multiply, a, b)

这有效。但是我想知道根据返回值的类型定义迭代逻辑是否是Pythonic。

我们还有其他方法可以更优雅地完成递归归约吗?

最佳答案

我认为你想做的是做一个递归版本的reduce。

def rreduce(f, init, default=None):                     
if default is None:
default = init[0]
init = init[1:]
if len(init) == 0:
return default
return rreduce(f, init[1:], f(default, init[0]))


>>> rreduce(lambda a, b: a*b, range(1,10))
362880
>>> rreduce(lambda a, b: a+b, ['t', 'a', 'c', 'o'])
'taco'

虽然递归很棒,但这并不是 Python 中 reduce 类型函数的首选方式,因为它很慢并且会遇到堆栈溢出 (HAA)

>>> rreduce(lambda a, b: a + [b], list(range(1, 10000)), [])
---------------------------------------------------------------------------
RecursionError Traceback (most recent call last)
<ipython-input-41-7dc07c5d9246> in <module>()
----> 1 rreduce(lambda a, b: a + [b], list(range(1, 10000)), [])

<ipython-input-33-37206eb8e39f> in rreduce(f, init, default)
5 if len(init) == 0:
6 return default
----> 7 return rreduce(f, init[1:], f(default, init[0]))

... last 1 frames repeated, from the frame below ...

<ipython-input-33-37206eb8e39f> in rreduce(f, init, default)
5 if len(init) == 0:
6 return default
----> 7 return rreduce(f, init[1:], f(default, init[0]))

RecursionError: maximum recursion depth exceeded in comparison

回答您的实际问题...

def lreduce(f, init, default=None):
if default is None:
return reduce(lambda x, a: x + [reduce(f, a)], init, [])
else:
return reduce(lambda x, a: x + [reduce(f, a, default)], init, [])

减少列表的列表。

>>> lreduce(lambda a, b: a + b, [range(10), range(10), range(10)])
[45, 45, 45]

之所以需要 if/else 是因为 reduce 作为 内置 不接受关键字参数:

In [56]: reduce(function=lambda a, b: a + b, sequence=range(10), initial=0)
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
<ipython-input-56-9fa3ed177831> in <module>()
----> 1 reduce(function=lambda a, b: a + b, sequence=range(10), initial=0)

TypeError: reduce() takes no keyword arguments

然后,如果您想更进一步......

def lreduceall(f, init, default=None):
if default is None:
return reduce(f, reduce(lambda x, a: x + [reduce(f, a)], init, []))
else:
return reduce(f, reduce(lambda x, a: x + [reduce(f, a, default)], init, []), default)

最后:

>>> lreduceall(lambda a, b: a + b, [range(10), range(10), range(10)])
135

关于Python中递归减少的Pythonic方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49792486/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com