【问题标题】:Non-recursive means of printing a list in Python在 Python 中打印列表的非递归方法
【发布时间】:2010-11-12 21:38:16
【问题描述】:

有没有办法以非递归方式执行以下操作:

my_list = [
    "level 1-1",
    "level 1-2",
    "level 1-3",
        [
            "level 2-1",
            "level 2-2",
            "level 2-3",
            [
                "level 3-1",
                "level 3-2"
            ]
        ],
    "level 1-4",
    "level 1-5"
    ]


def print_list(the_list, indent_level=0):
    for item in the_list:
        if isinstance(item, list):
            print_list(item, indent_level + 1)
        else:
            print "\t" * indent_level, item


print_list(my_list)

【问题讨论】:

  • 这是一个谜题还是真的需要某个地方?我很好奇。
  • 只是试图找到解决此类问题的最有效方法。这不是一个难题,但我提供的代码只是一个示例。
  • 这也是标准的第一年或第二年 CS 算法。 :)
  • 另请注意,迭代执行此操作不一定比递归执行此操作更快。事实上,在快速测试中(100k 运行没有输出),你的代码是最快的:1600ms;我的是1750,马丁的是2000ms。具有大量非叶节点的图的平衡可能会有所不同,因为它会递归更多。
  • 通过非递归执行它并不会真正购买太多,因为您无法避免周围有堆栈(假设可能无限深度)。

标签: python recursion


【解决方案1】:

这是 Martin Löwis 版本的变体,它使用 for/else 而不是手动捕获 StopIteration,和 len(stack) 而不是跟踪缩进级别。

def print_list(the_list):
    stack = [iter(the_list)]
    while stack:
        for item in stack[-1]:
            if isinstance(item, (list, tuple)):
                stack.append(iter(item))
                break
            else:
                print '\t' * (len(stack)-1), item
        else:
            stack.pop()

【讨论】:

    【解决方案2】:

    每个人都给出了解决方案

    • 生产就绪
    • 使用栈,所以和递归有同样的问题
    • 或多次浏览列表

    这里是一个解决方案横向解决方案:)

    • 尚未准备好生产,但很有趣
    • 没有堆栈或类似的东西,看不到列表

    --

    def my_print(the_list):
        level = -1
        out = []
        levelUp="levelup"
        levelDown="leveldown"
    
        s =  repr(the_list).replace("', '","\n").replace(
            "', ['", "\n%s\n"%levelUp).replace("['", "\n%s\n"%levelUp).replace(
            "']", "\n%s\n"%levelDown).replace("], '", "\n%s\n"%levelDown)
    
        for line in s.splitlines():
            if not line: continue
            if line == levelUp:
                level+=1
            elif line == levelDown:
                level-=1
            else:
                print "\t"*level,line
    
    my_print(my_list)
    

    它假定您的列表文本不会有一些特殊的子字符串。

    【讨论】:

      【解决方案3】:
      stack = [(my_list, -1)]
      while stack:
          item, level = stack.pop()
      
          if isinstance(item, list):
              for i in reversed(item):
                  stack.append((i, level+1))
          else:
              print "\t" * level, item
      

      【讨论】:

        【解决方案4】:

        请注意,这取决于不包含元组的输入。

        l1 = my_list
        done = False
        
        # Repeatedly turn the list elements into tuples of the form
        # (indent, item) until there are no more lists.
        while not done:
            done = True
            l2 = []
            for item in l1:
                if isinstance(item,tuple):
                    indent = item[0]
                    item = item[1]
                else:
                    indent = 0
                if isinstance(item,list):
                    l2.extend( zip( (indent + 1,) * len(item), item) )
                    done = False
                else:
                    l2.append((indent,item))
            l1 = l2
        
        for indent, item in l1:
            print "\t" * indent, item
        

        【讨论】:

          【解决方案5】:
          def print_list(the_list, indent_level=0):
              stack = [iter(the_list)]
              while stack:
                  try:
                      item = stack[-1].next()
                  except StopIteration:
                      stack.pop()
                      indent_level -= 1
                      continue
                  if isinstance(item, list):
                      indent_level += 1
                      stack.append(iter(item))
                  else:
                      print "\t" * indent_level, item
          

          【讨论】:

          • 一堆迭代器——可爱。我喜欢我的更好一点(简洁,而且稍微快一点——无论如何对我来说),但是这个避免了复制整个树,如果它非常大和宽,这可能会有所帮助。不过,您可能需要数百万个节点才能发挥作用。
          猜你喜欢
          • 2020-08-10
          • 1970-01-01
          • 2014-11-27
          • 2023-03-15
          • 1970-01-01
          • 2020-12-05
          • 2017-06-22
          • 2012-07-23
          • 1970-01-01
          相关资源
          最近更新 更多