python中的递归映射

python中的递归映射,python,recursion,Python,Recursion,将递归函数应用于结构化/嵌套列表/列表理解并返回相同结构的结构化/嵌套列表/列表理解,最适合的方法是什么 一个简单的工作示例: list1 = [[[1,2,3],[2,3,5],[5,2,2]], [[1,2],[3,1],[3,4]], [[2,3,4]] list2 = [[[3,2,4],[2,1,1],[2,2,2]],[[3,3],[2,2],[1,1]],[[2,2,2]]] 我需要一个递归函数,该函数对list1的结构具有鲁棒性, list2甚至更多,以及普通函数lambda

将递归函数应用于结构化/嵌套列表/列表理解并返回相同结构的结构化/嵌套列表/列表理解,最适合的方法是什么

一个简单的工作示例:

list1 = [[[1,2,3],[2,3,5],[5,2,2]], [[1,2],[3,1],[3,4]], [[2,3,4]]
list2 = [[[3,2,4],[2,1,1],[2,2,2]],[[3,3],[2,2],[1,1]],[[2,2,2]]]
我需要一个递归函数,该函数对
list1
的结构具有鲁棒性,
list2
甚至更多,以及普通函数
lambda x,y:x*y
。在这个小小的例子中,理想的结果是:

result = [[[3,4,12],[4,3,5],[10,4,4]],[[3,6],[6,2],[3,4]],[[4,6,8]]]
使用
list1
list3
的另一个示例,其中
list3
是:

list3 = [[[3],[2],[2]],[[3],[2],[1]],[[2]]]
期望的结果是:

result = [[[3,6,9],[4,6,10],[10,4,5]], [[3,6],[6,2],[3,4]], [[4,6,8]]
您可以使用内置函数和

输出:

[[[3, 4, 12], [4, 3, 5], [10, 4, 4]], [[3, 6], [6, 2], [3, 4]], [[4, 6, 8]]]
说明:

实际上您首先要做的是,您将得到两个列表,分别是
list1
list2

[[1,2,3],[2,3,5],[5,2,2]]
[[3,2,4],[2,1,1],[2,2,2]]
然后在这些列表中,以相同的方式访问:

[1,2,3]
[3,2,4]
然后:

1
3
然后对所有数据简单地应用
x*y
,依此类推


希望这对您有所帮助。

如果您希望看到一个递归解决方案,如果您的列表可以任意嵌套,您可能会选择以下方式:

>>> list1 = [[[1,2,3],[2,3,5],[5,2,2]], [[1,2],[3,1],[3,4]], [[2,3,4]]]
>>> list2 = [[[3,2,4],[2,1,1],[2,2,2]],[[3,3],[2,2],[1,1]],[[2,2,2]]]
>>> def parallel_apply(l1, l2, f):
...     if isinstance(l1, list) and isinstance(l2, list):
...         return [parallel_apply(x,y, f) for x,y in zip(l1,l2)]
...     elif not isinstance(l1, list) and not isinstance(l2, list):
...         return f(l1, l2)
...     else:
...         raise ValueError("Structures incompatible for parallel apply")
...
>>> parallel_apply(list1, list2, lambda x,y: x*y)
[[[3, 4, 12], [4, 3, 5], [10, 4, 4]], [[3, 6], [6, 2], [3, 4]], [[4, 6, 8]]]

注意,Python具有最大递归深度,并且没有尾部调用优化。如果列表可以嵌套得很深,那么您可能必须将其转换为迭代解决方案

因此,您可以始终保证
list1
list2
具有相同的结构?不一定,它们可以具有不同的结构,这取决于所应用的函数,有时可能会有一个或多个额外的列表,作为“常量”列表,在结构之间保持不变……嗯,在您的示例3中,您如何知道如何处理它
lambda x:yx*y
不会像R中那样给出元素乘法。@shenglih注意,这不会处理您有
list3
的情况。它变得有点复杂,但本质上,我认为这给了你一个基本方法的想法,你可以扩展到处理你的特殊情况。
>>> list1 = [[[1,2,3],[2,3,5],[5,2,2]], [[1,2],[3,1],[3,4]], [[2,3,4]]]
>>> list2 = [[[3,2,4],[2,1,1],[2,2,2]],[[3,3],[2,2],[1,1]],[[2,2,2]]]
>>> def parallel_apply(l1, l2, f):
...     if isinstance(l1, list) and isinstance(l2, list):
...         return [parallel_apply(x,y, f) for x,y in zip(l1,l2)]
...     elif not isinstance(l1, list) and not isinstance(l2, list):
...         return f(l1, l2)
...     else:
...         raise ValueError("Structures incompatible for parallel apply")
...
>>> parallel_apply(list1, list2, lambda x,y: x*y)
[[[3, 4, 12], [4, 3, 5], [10, 4, 4]], [[3, 6], [6, 2], [3, 4]], [[4, 6, 8]]]