将递归函数应用于结构化/嵌套列表/列表理解并返回相同结构的结构化/嵌套列表/列表理解的最pythonic方法是什么?
最小的工作示例:
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]]
答案 0 :(得分:1)
您可以使用zip内置函数和list comprehension
执行此操作result = [[[x*y for x,y in zip(c,d)]for c,d in zip(a,b)] for a,b in zip(list1,list2)]
输出:
[[[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
应用于他们,依此类推所有数据。
希望这有用。
答案 1 :(得分:0)
如果你想看到一个递归的解决方案,如果你的列表可以任意嵌套,你可能更喜欢这样的东西:
>>> 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具有最大递归深度且没有尾调用优化。如果您的列表可以嵌套非常深,那么您可能必须将其转换为迭代解决方案。