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]およびie サブインデント行A[3]の子です。A[1]

次の形式になる出力リストを取得しようとしています。

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

このように反復するB[x][0]と、最初のレベルのインデントされたアイテムのみが取得され、各要素に再帰的に移動できます。

アルゴリズムは無限の深さを処理できる必要があります。つまりA[3]、要素が続く場合は[3,'z']、のネストされたリストにする必要がありA[3]ます。

同様の問題を解決して使用する他の投稿をいくつか調べましitertools.groupbyたが、残念ながら、私の問題に適用できるほど十分に理解できていません。

助けてくれて本当にありがとう!

4

2 に答える 2

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