所以这是我的问题:
我已成功将带行缩进级别的文本文件解析为如下列表:
A = [[1,'a'],[1,'b'],[2,'c'],[2,'d'],[1,'e'],[2,'f']]
列表A
中的每个元素都是长度为2的列表。每个元素对应于从文本文件中读取的行。 A[x][0]
是文本文件中该行的indent level
,A[x][1]
是x
是A
中任何元素的索引的行的内容。
例如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
的帖子,但遗憾的是,他们无法理解它们,无法将其应用到我的问题中。
非常感谢您的帮助人员!
答案 0 :(得分: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']]]
答案 1 :(得分:0)
递归解决方案,方法返回给定级别的输入列表的一部分的格式化列表。格式就像Lev描述的那样,因为它是一致的。注意:方法会破坏输入列表。
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