我正在编写将CSV转换为XML的代码。假设我有一个单独的列表:
enum class dayOfWeek : short { M = 10, TU, W, TH, F, SA, SU };
int main()
{
dayOfWeek d = dayOfWeek::TU;
int u = static_cast<int>(d);
return 0;
}
此列表的每个切片以“name”开头,表示具有名称,值和可变标记值对的可变数量的元素。
我想把它变成:
input = ['name', 'val', 0, \
'name', 'val', 1, 'tag', 'val', \
'name', 'val', 2, 'tag', 'val', 'tag', 'val', \
'name', 'val', 0]
无需将标记值对分隔为元组,这是在单独的方法中处理的。我有一个解决方案,但它不是非常pythonic:
output = [['name', 'val', []],
['name', 'val', ['tag', 'val']],
['name', 'val', ['tag', 'val', 'tag', 'val']],
['name', 'val', []]]
我认为我可以将其作为列表理解来实现,但每个元素的可变长度都会让我陷入循环。输入是从CSV解析的,我可以更改格式以更好地适应不同的解决方案。想法?
答案 0 :(得分: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文件具有您应该使用的结构。即,不要将二维数据展平,因此您需要将其展开。但你的问题很有意思: - )
答案 1 :(得分:1)
我不知道 pythonic 你是怎么想的,但是你可以做这样的事情
finallist = []
therest = x
while therest:
name, val, count, *therest = therest
sublist, therest = rest[:2*count], rest[2*count:]
finallist.append([name, val] + [sublist])
答案 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'], []]
答案 3 :(得分: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"
]
])
虽然真的很难看。