2017-10-20 13 views
2

私はCSVをXMLに変換するコードを書いています。可変長の複数の要素を持つPythonリストの理解?

input = ['name', 'val', 0, \ 
     'name', 'val', 1, 'tag', 'val', \ 
     'name', 'val', 2, 'tag', 'val', 'tag', 'val', \ 
     'name', 'val', 0] 

「名前」で始まるこのリストのすべてのスライスは名前、値、およびオプションのタグと値のペアの可変数を持つ要素を表す:私のような単一のリストを持っていると仮定します。私はにこれを有効にしないようにしたい

output = [['name', 'val', []], 
      ['name', 'val', ['tag', 'val']], 
      ['name', 'val', ['tag', 'val', 'tag', 'val']], 
      ['name', 'val', []]] 

タプルにタグと値のペアを分離する必要が、これは別の方法で処理されます。私は解決策を持っているが、それは非常にニシキヘビではありません。

output=[] 
cursor=0 

while cursor < len(input): 
    name=input[cursor] 
    val=input[cursor+1] 
    ntags=int(input[cursor+2]) 
    optslice=input[cursor+3:cursor+3+2*ntags] 
    cursor = cursor+3+2*ntags 
    print name, val, ntags, optslice, cursor 
    output.append([name, val, optslice])  
print output 

> name val 0 [] 3 
> name val 1 ['tag', 'val'] 8 
> name val 2 ['tag', 'val', 'tag', 'val'] 15 
> name val 0 [] 18 

> [['name', 'val', []], ['name', 'val', ['tag', 'val']], ['name', 'val', ['tag', 'val', 'tag', 'val']], ['name', 'val', []]] 

私はおそらくリスト内包としてこれを行うことができると思いますが、各要素の可変長は、ループのための私を投げています。入力はCSVから解析され、別のソリューションに合わせてフォーマットを変更できます。アイデア?

答えて

1

私はあなたがこれを考慮する方法ニシキヘビ知りませんが、あなたは、私が代わりにあなたのカーソルのイテレータを使用して、for name in itと理解を推進したい。この

finallist = [] 
therest = x 

while therest: 
    name, val, count, *therest = therest 
    sublist, therest = rest[:2*count], rest[2*count:] 
    finallist.append([name, val] + [sublist]) 
6

ような何かを行うことができます。

it = iter(input) 
output = [[name, next(it), [next(it) for _ in range(2 * next(it))]] for name in it] 

それともislice

:言っ

from itertools import islice 

it = iter(input) 
output = [[name, next(it), list(islice(it, 2 * next(it)))] for name in it] 

は、私はあなたが最初の場所でそのフラットリスト内のすべてのデータを持つべきではないと思います。 CSVファイルには、代わりに使用する必要がある構造が存在する可能性があります。つまり、2次元データをフラット化しないでください。フラット化する必要があります。しかし、あなたの質問はここで

0

:-)それにもかかわらず、興味深いです私のコードです:

data = ['name', 'val', 0, 
     'name', 'val', 1, 'tag', 'val', 
     'name', 'val', 2, 'tag', 'val', 'tag', 'val', 
     'name', 'val', 0] 

tmp = [ 
    [ 
     data[pos:pos + 2], 
     [i for i in data[pos + 3:pos + 3 + data[pos + 2] * 2]] 
    ] for pos, e in enumerate(data) if e == 'name'] 

for e in tmp: 
    print e 

出力は次のとおりです。

# [['name', 'val'], []] 
# [['name', 'val'], ['tag', 'val']] 
# [['name', 'val'], ['tag', 'val', 'tag', 'val']] 
# [['name', 'val'], []] 
0

あなたは本当に純粋なリストの内包表記を使用する場合:

a = ['name', 'val', 0, \ 
       'name', 'val', 1, 'tag', 'val', \ 
       'name', 'val', 2, 'tag', 'val', 'tag', 'val', \ 
       'name', 'val', 0] 


print(
[grouped[:2] + [tag for tag in grouped[3:]] for grouped in 
    [ 
     a[i:i+(a[i+1:].index("name") + 1 if a[i+1:].count("name") else len(a[i:])+1)] 
     for i, x in enumerate(a) if x == "name" 
    ] 
]) 

それは本当に醜いです。

関連する問題