使用zip()旋转lis

2024-09-28 23:37:32 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一组从数据库返回的记录,格式如下:

data = [
    ["date", "value1a", "value2a", "value3a", ...],
    ["date", "value1b", "value2b", "value3b", ...]
]

我想把这组行变成一个像

^{pr2}$

我知道zip()会做这种事情,但我不清楚如何将日期放入每个记录(并使它们成为元组)。从数据库返回的行的长度并不总是相同的,但我将知道每次调用中的预期长度。在


Tags: 数据库datadate格式记录zip事情元组
3条回答
data = [["date_a", "1a", "2a", "3a"], 
        ["date_b", "1b", "2b", "3b"]]

print zip(*(zip(itertools.repeat(ls[0]), ls[1:]) for ls in data))

给予

^{pr2}$

有关一些有用的变体,请参见注释。在

编辑:这是基于最初的问题,假设数据将在一个列表中,而不是多个输入列表中。对问题的编辑已经清楚地表明不是这样,所以我建议您遵循Janne Karila's solution。在

假设您知道有多少个不同的值,这是一个很好的解决方案,使用itertools'^{} recipe

import itertools

def grouper(n, iterable, fillvalue=None):
     args = [iter(iterable)] * n
     return itertools.zip_longest(fillvalue=fillvalue, *args)

data = ["date", "1a", "2a", "3a", "1b", "2b", "3b", "1c", "2c", "3c"]
first = data.pop(0)
print([list(zip(itertools.repeat(first), items)) for items in zip(*grouper(3, data))])

给我们:

^{pr2}$

请注意,如果没有足够的值,这将用Nones填充列表。在

{a3}如果你不想显示,就自然地使用。E、 g组:

(zip(itertools.repeat(first), items) for items in zip(*grouper(3, data)))

请注意,我使用的是python3.x,因此在2.x下,无论我在哪里使用zip(),您可能想要itertools.izip(),而{}变成{}。在

请注意,更好的方法是假设您知道定义的值应该在第一个列表中,什么应该在第二个列表中,等等。。。在

import itertools
import operator

data = ["date", "1a", "2a", "3a", "1b", "2b", "3b", "1c", "2c", "3c"]
first = data.pop(0)

print([list(zip(itertools.repeat(first), items)) for _, items in itertools.groupby(sorted(data), operator.itemgetter(0))])

产生:

^{pr2}$

当然,这只适用于给定的示例,假设您的实际数据不同,您将希望将operator.itemgetter(0)更改为一个函数,该函数定义您的项应分组到哪个列表中。在

请注意,我们可能需要封装前缀工作:

def prefix(iterable, prefix):
    """Returns every element of an iterable prefixed with a given value."""
    #prefix("ABCDEFG", "x") --> ("x", "A"), ("x", "B"), ("x", "C"), ("x", "D"), ...
    return zip(itertools.repeat(prefix), iterable)

我们只需:

(prefix(items, first) for items in zip(*grouper(3, data)))

以及

(prefix(items, first) for _, items in itertools.groupby(sorted(data), operator.itemgetter(0)))

更具可读性。在

对第一个元素使用itertools repeat:

zip(itertools.repeat(ls[0]), ls[1:])

相关问题 更多 >