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]]]