代码之家  ›  专栏  ›  技术社区  ›  MarkokraM

在Python中从没有映射递归的列表/元组构造带圆括号的嵌套字符串

  •  0
  • MarkokraM  · 技术社区  · 5 年前

    我想通过省略一些递归调用并用while或其他迭代循环替换它们来优化我的代码。

    递归函数如下:

    def repr(e):
        if isinstance(e, (list, tuple)):
            return "(%s)" % " ".join(map(repr, e))
        return str(e)
    

    repr([1, [2, [3, 4]]]) (1 (2 (3 4)))

    0 回复  |  直到 5 年前
        1
  •  1
  •   cdlane    5 年前

    名字 repr 已经属于Python内置函数,因此与其重新定义它,不如假设您的代码是:

    def my_repr(e):
        if isinstance(e, (list, tuple)):
            return "(%s)" % " ".join(map(my_repr, e))
    
        return str(e)
    

    假设您不想进行简单的字符串操作,而是实际遍历列表,我们可以替换 隐性的 递归堆栈 堆栈:

    def my_repr(e):
        stack = [e]
    
        result = ""
    
        while stack:
            item = stack.pop()
    
            if isinstance(item, (list, tuple)):
                stack.append(")")
                stack.extend(reversed(item))
                result += "("
            elif item == ")":
                result += item
            else:
                result += str(item) + " "
    
        return result
    

    item 作为将其添加到字符串的一部分,例如:

                result += str(item * item) + " "
    

    输出字符串现在包含输入结构中数字的平方。或者别的什么。

    C类 reversed() . 这种非递归实现的一个优点是,大型、复杂的输入不应该像递归输入一样,触发Python的调用堆栈限制。

        2
  •  1
  •   Mojtaba Kamyabi    5 年前
    def repr(e):
        return str(e).replace("[", "(").replace("]", ")").replace(",", " ")
    

    例子:

    >>> repr([1, [2, [3, 4]]])
    '(1 (2 (3 4)))'
    

    timeit 这样的模块:

    import timeit
    
    def repr1(e):
        if isinstance(e, (list, tuple)):
            return "(%s)" % " ".join(map(repr, e))
        return str(e)
    
    def repr2(e):
        return str(e).replace("[", "(").replace("]", ")").replace(",", " ")
    
    
    duration1 = timeit.timeit('repr1([1, [2, [3, 4]]])', 'from __main__ import repr1',number=1000)
    duration2 = timeit.timeit('repr2([1, [2, [3, 4]]])', 'from __main__ import repr2', number=1000)
    
    print(duration1, duration2)
    

    对于更大的列表 list(range(10000)) :

    print(duration1, duration2)
    # 1.0414706510000542 0.7595879010000317
    

    str.translate() :

    def repr3(e):
        table = str.maketrans("[],", "() ")
        return str(e).translate(table)