【问题标题】:Python: Read a list with tree depth level and output a tree like nested listPython:读取具有树深度级别的列表并输出类似嵌套列表的树
【发布时间】:2012-12-14 09:32:13
【问题描述】:

这是我的问题:

我已成功将行缩进级别的文本文件解析为如下列表:

A = [[1,'a'],[1,'b'],[2,'c'],[2,'d'],[1,'e'],[2,'f']]

列表A 中的每个元素都是长度为2 的列表。每个元素对应于从文本文件中读取的一行。 A[x][0] 是文本文件中该行的indent levelA[x][1] 是该行的内容,其中xA 中任何元素的索引。

例如A[1] = [1,'b'] 其中1 是缩进级别,'b' 是行文本。 A[2]A[3]A[1] 的子级,即子缩进行。

我正在尝试获取以下格式的输出列表:

B = [['a'],['b',['c','d']],['e',['f']]]

这样,当我遍历 B[x][0] 时,我将只获得第一级缩进项,并且能够递归地转到每个元素。

该算法应该能够处理无限深度,即如果 A[3] 后跟元素 [3,'z'] 它应该是 A[3] 的嵌套列表。

我探索了一些解决类似问题的其他帖子并使用itertools.groupby,但遗憾的是无法充分理解它们,无法将其应用于我的问题。

非常感谢您的帮助!

【问题讨论】:

  • 为什么'b' 在子列表中,尽管它与'a' 处于同一级别?那么为什么'd' 不在它自己的子列表中呢?你能澄清一下规则吗?
  • -a -b --c --d -e --f 所以 c 和 d 与 b 相关,f 与 e 相关。根列表将只包含来自级别 1 的元素,即 a、b 和 e,但由于 b 和 e 有子节点,如果将 bi 作为根列表的元素添加,则与子节点的关系将丢失
  • 不会丢失:在['a', 'b', ['c', 'd'], 'e', ['f']] 中,每个子列表都与前一个元素“相关”。

标签: python list recursion tree nested


【解决方案1】:

试试这个简单的基于堆栈的算法:

A = [[1,'a'],[1,'b'],[2,'c'],[2,'d'],[1,'e'],[2,'f']]
stack = [ [] ]
for level, item in A:
    while len(stack) > level:
        stack.pop()
    while len(stack) <= level:
        node = (item, [])
        stack[-1].append(node)
        stack.append(node[1])

result = stack[0]

这将创建一个类似的结构:

[('a', []), ('b', [('c', []), ('d', [])]), ('e', [('f', [])])]

哪个,IMO,使用起来更方便,但如果需要,将其转换为您的应该没问题:

def convert(lst):
    return [ [x, convert(y)] if y else x for x, y in lst]

result = convert(stack[0])
print result
# ['a', ['b', ['c', 'd']], ['e', ['f']]]

【讨论】:

  • A = [[1,'a'],[3,'b']] 工作不正常。用node = ((item if len(stack) == level else None), []) 换行node = (item, []) 修复它。
  • 谢谢!这几乎就是我想要的。我们如何在没有空列表的情况下获得输出?
【解决方案2】:

递归解决方案,该方法返回输入列表的一部分的格式化列表,该列表位于给定级别或低于给定级别。格式就像列夫描述的那样,因为它是一致的。注意:方法会破坏输入列表。

A = [[1,'a'],[1,'b'],[2,'c'],[2,'d'],[4,'x'],[5,'y'],[1,'e'],[2,'f']]

def proc_indent(level, input_list):
  if not input_list or level > input_list[0][0]:
    return None
  this_level = input_list.pop(0)[1] if level == input_list[0][0] else None
  up_levels = []
  while True:
    r = proc_indent(level+1, input_list)
    if r is None:
      break
    up_levels.append( r )
  if not up_levels:
    return [this_level]
  up_levels = [i for u in up_levels for i in u]
  return [this_level, up_levels] if this_level else [up_levels]

print proc_indent(0, list(A))  # copy list, since it is destructed in a recursion

【讨论】:

    猜你喜欢
    • 2011-08-27
    • 2023-03-03
    • 1970-01-01
    • 2020-05-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多