Python:在递归迭代上映射函数

Vee*_*ech 12 python recursion dictionary

我有一个任意嵌套的迭代,如下所示:

numbers = (1, 2, (3, (4, 5)), 7)
Run Code Online (Sandbox Code Playgroud)

我想在不改变结构的情况下将函数映射到它上面.例如,我可能想要将所有数字转换为字符串来获取

strings = recursive_map(str, numbers)
assert strings == ('1', '2', ('3', ('4', '5')), '7')
Run Code Online (Sandbox Code Playgroud)

有一个很好的方法来做到这一点?我可以成像编写我自己的方法来手动遍历numbers,但我想知道是否有一种通用的方法来映射递归的迭代.

另外,在我的例子中,如果strings给我嵌套列表(或一些可迭代的)而不是嵌套的元组也没关系.

Uri*_*iel 16

我们扫描的顺序进行到更深的递归的每一个元素,如果当前项目是子序列,或产生它的映射,如果我们达到了一个非序列数据类型(可能是int,str或任何复杂的类).

我们collections.Sequence用来概括每个序列的概念,而不仅仅是元组或列表,并且type(item)在产量方面确保我们得到的子序列保持与它们相同的类型.

from collections import Sequence

def recursive_map (seq, func):
    for item in seq:
        if isinstance(item, Sequence):
            yield type(item)(recursive_map(item, func))
        else:
            yield func(item)
Run Code Online (Sandbox Code Playgroud)

演示:

>>> numbers = (1, 2, (3, (4, 5)), 7)
>>> mapped = recursive_map(numbers, str)
>>> tuple(mapped)
('1', '2', ('3', ('4', '5')), '7')
Run Code Online (Sandbox Code Playgroud)

或者更复杂的例子:

>>> complex_list = (1, 2, [3, (complex('4+2j'), 5)], map(str, (range(7, 10))))
>>> tuple(recursive_map(complex_list, lambda x: x.__class__.__name__))
('int', 'int', ['int', ('complex', 'int')], 'map')
Run Code Online (Sandbox Code Playgroud)


Ily*_*rov 6

def recursive_map(f, it):
    return (recursive_map(f, x) if isinstance(x, tuple) else f(x) for x in it)
Run Code Online (Sandbox Code Playgroud)