[英]Python list comprehension with multiple elements of variable length?
我正在編寫代碼將CSV轉換為XML。 假設我有一個列表,如:
input = ['name', 'val', 0, \
'name', 'val', 1, 'tag', 'val', \
'name', 'val', 2, 'tag', 'val', 'tag', 'val', \
'name', 'val', 0]
此列表的每個切片以“name”開頭,表示具有名稱,值和可變標記值對的可變數量的元素。
我想把它變成:
output = [['name', 'val', []],
['name', 'val', ['tag', 'val']],
['name', 'val', ['tag', 'val', 'tag', 'val']],
['name', 'val', []]]
無需將標記值對分隔為元組,這是在單獨的方法中處理的。 我有一個解決方案,但它不是非常pythonic:
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解析的,我可以更改格式以更好地適應不同的解決方案。 想法?
我將使用迭代器而不是光標,然后使用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文件具有您應該使用的結構。 即,不要將二維數據展平,因此您需要將其展開。 但你的問題很有意思:-)
我不知道你怎么認為pythonic ,但你可以做這樣的事情
finallist = []
therest = x
while therest:
name, val, count, *therest = therest
sublist, therest = rest[:2*count], rest[2*count:]
finallist.append([name, val] + [sublist])
這是我的代碼:
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"
]
])
這真的很難看。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.