2017-10-20 136 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', []]] 

無需標籤 - 值對分離到的元組,這是在一個單獨的方法來處理。我有一個解決方案,但它不是非常符合Python:

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

我不知道該怎麼Python的你考慮這一點,但你可以做這樣的事情

finallist = [] 
therest = x 

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

我會用一個迭代器,而不是你的光標,然後開車的理解與for name in it

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文件具有您應該使用的結構。也就是說,不要弄平二維數據,所以你需要將它解開。但是你的問題很有趣仍然:-)

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" 
    ] 
]) 

雖然它確實很醜。