Python列表理解具有可变长度的多个元素?

时间:2017-10-20 12:50:56

标签: python python-2.7 list-comprehension

我正在编写将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解析的,我可以更改格式以更好地适应不同的解决方案。想法?

4 个答案:

答案 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"
    ]
])

虽然真的很难看。