0

所以这是我的问题:

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

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

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

例如A[1] = [1,'b']1缩进级别和'b'行文本在哪里。 A[2]并且A[3]A[1]ie 子缩进行的子代。

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

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

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

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

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

真的很感谢你们的帮助!

4

2 回答 2

0

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

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']]]
于 2012-12-29T12:24:50.053 回答
0

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

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
于 2012-12-29T14:39:55.933 回答