带有多个可变长度元素的Python列表理解?
问题描述:
我正在编写将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解析的,我可以更改格式以更好地适应不同的解决方案。想法?
答
我不知道该怎么Python的你考虑这一点,但你可以做这样的事情
finallist = []
therest = x
while therest:
name, val, count, *therest = therest
sublist, therest = rest[:2*count], rest[2*count:]
finallist.append([name, val] + [sublist])
答
我会用一个迭代器,而不是你的光标,然后开车的理解与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文件具有您应该使用的结构。也就是说,不要弄平二维数据,所以你需要将它解开。但是你的问题很有趣仍然:-)
答
这里是我的代码:
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'], []]
答
如果你真的想用纯列表理解:
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"
]
])
虽然它确实很丑。