2016-09-24 4 views
0
repeating_group_field = ['a', 'b', 'c'] 


ddata = ['l', 'm', 'n', 2, 'a', 'b', 'a', 'c', 'b', 'g', 'h', 2, 'c', 'c', 'l', 2, 'b', 'b'] 

# output = ['l', 'm', 'n', [['a', 'b'],['a', 'c', 'b']], 'g', 'h', [['c'], ['c']], 'l', 2, [[b], [b]]] 


def outer(it): 
    last = {'value': None} 

    def rgroup(i, it): 

     def group(delim, it): 
      yield delim 
      for i in it: 
       if i in repeating_group_field and i is not delim: 
        yield i 
       else: 
        last['value'] = i 
        return 
      last['value'] = None 
     delim = it.next() 
     for x in range(i): 
      yield [y for y in group(delim, it)] 

    for i in it: 
     if type(i) is int: 
      yield [x for x in rgroup(i, it)] 
      if last['value']: 
       yield last['value'] 
     else: 
      yield i 

it = iter(ddata) 
result = [z for z in outer(it)] 

print result 



def flatter(dataset): 
    iterator = iter(dataset) 
    for datum in iterator: 
     if type(datum) is int: 
      acc = [] 
      delim = iterator.next() 
      for n in range(datum): 
       subacc = [] 
       subacc.append(delim) 
       while True: 
        try: 
         repeating_group_element = iterator.next() 
         if repeating_group_element not in repeating_group_field: 
          acc.append(subacc) 
          yield acc 
          yield repeating_group_element 
          break 
         if repeating_group_element != delim: 
          subacc.append(repeating_group_element) 
         else: 
          acc.append(subacc) 
          break 
        except StopIteration: 
         acc.append(subacc) 
         yield acc 
         return 
     else: 
      yield datum 

g = [y for y in flatter(ddata)] 

print g 

入力データを目的の内部データ構造に変換するための上記の2つの作業アルゴリズムを示しました。入力データの規則は次のとおりです。入力のintは繰り返しグループを示し、繰り返しグループインジケータに続く最初の要素は繰り返しグループデリミタです。入力データ内の区切り文字の表示は、繰り返しグループの次のインスタンスの開始を示します。繰返グループのエレメント数は繰返グループヘッダで指定されていません。入力ストリームに非繰り返しグループフィールドが存在することは、繰り返しグループの終了を示します。入力の検証は必要ありません。慣用の繰り返しグループファイル形式の解析

最初の実装ではネストされた関数を使用し、アキュムレータは使用しません。 2番目の実装はより平坦で、アキュムレータを使用します。私はPythonでこのアルゴリズムを実装するより慣用的な方法があるのだろうかと思っています。

答えて

1

私は、このような洗練されたデータ再パッキング手順では、何かが明確かつ単純であるとは思えません。

私はこれをゼロから修正しましたが、決して美しく見えません(しかし、私にはより単純に見えますが)。

def chew_data(data): 
    def check_type(char): 
     nonlocal inside_group 
     if type(char) is int: 
      inside_group = True 
     else: 
      inside_group = False 
      return char 

    inside_group = False 
    group_delimiter = '' 
    group_result = [] 
    subgroup_result = [] 
    for c in data: 
     if not inside_group: 
      if check_type(c): 
       yield c 
     else: 
      if c == group_delimiter: 
       group_result.append(subgroup_result) 
       subgroup_result = [] 
      if not group_delimiter: 
       group_delimiter = c 
      if c in repeating_group_field: 
       subgroup_result.append(c) 
      else: 
       group_result.append(subgroup_result) 
       subgroup_result = [] 
       yield group_result 
       group_result = [] 
       group_delimiter = '' 
       if check_type(c): 
        yield c 
    group_result.append(subgroup_result) 
    yield group_result 
+0

ご回答ありがとうございます。間違いなくより良い変数名!私は、私がSOに投稿する前に、テストケースで変数の名前を変更することを覚えておく必要があります。 – shaz

+1

@shaz、私はこの質問がCodeReviewハブに属していると思います。あなたのコードではすべてが期待通りに機能し、レビューを求めています。あなたはおそらくガイドラインを確認する必要がありますが、私はこれについてはあまりよく分かりません。 –

関連する問題