2017-10-20 78 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" 
    ] 
]) 

虽然它确实很丑。

相关问题