簡體   English   中英

Python列表理解具有可變長度的多個元素?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM