按值和日期合并列表

时间:2017-05-18 04:24:32

标签: python

我有一个sql query结果集,我需要转置它以适应图表应用程序。

[(1, '2017-01-01', 2), 
 (1, '2017-02-01', 4),
 (1, '2017-03-01', 6), 
 (1, '2017-04-01', 8), 
 (2, '2017-01-01', 20),
 (2, '2017-02-01', 40),
 (2, '2017-03-01', 60),
 (2, '2017-04-01', 80),
 (3, '2017-01-01', -1),
 (3, '2017-02-01', -2),
 (3, '2017-03-01', -3),
 (3, '2017-04-01', -4)]

我需要

[('2017-01-01', 2, 20, -1), 
 ('2017-02-01', 4, 40, -2),
 ('2017-03-01', 6, 60, -3), 
 ('2017-04-01', 8, 80, -4)]

按日期合并并将每个值相对于第一列的值存储

刚接触python我不能找到最好的方法,我怀疑list comprehension可能适合这个。

任何建议都非常感谢

2 个答案:

答案 0 :(得分:3)

就个人而言,我会使用OrderedDict,因此您可以直接按日期访问每个列表:

import collections

result = [(1, '2017-01-01', 2), (1, '2017-02-01', 4), (1, '2017-03-01', 6), (1, '2017-04-01', 8), (2, '2017-01-01', 20), (2, '2017-02-01', 40), (2, '2017-03-01', 60), (2, '2017-04-01', 80), (3, '2017-01-01', -1), (3, '2017-02-01', -2), (3, '2017-03-01', -3), (3, '2017-04-01', -4)]

d = collections.OrderedDict()

for tup in result:
    key = tup[1]
    d.setdefault(key,[]).append(tup[2])

结果:

print(d)
OrderedDict([('2017-01-01', [2, 20, -1]), ('2017-02-01', [4, 40, -2]), ('2017-03-01', [6, 60, -3]), ('2017-04-01', [8, 80, -4])])

d['2017-01-01']将返回[2, 20, -1]等等。

如果您确实需要该列表结构,您实际上可以从创建的字典构建它:

final_result = []

for k,v in d.items():
    final_result.append(tuple([k]+v))

结果:

print(final_result)
[('2017-01-01', 2, 20, -1), ('2017-02-01', 4, 40, -2), ('2017-03-01', 6, 60, -3), ('2017-04-01', 8, 80, -4)]

你也可以做第二步作为列表理解:

[tuple([k]+v) for k,v in d.items()]

这是一个Jython实现(它的算法速度较慢,但​​仍然可以满足您的需求):

result = [(1, '2017-01-01', 2), (1, '2017-02-01', 4), (1, '2017-03-01', 6), (1, '2017-04-01', 8), (2, '2017-01-01', 20), (2, '2017-02-01', 40), (2, '2017-03-01', 60), (2, '2017-04-01', 80), (3, '2017-01-01', -1), (3, '2017-02-01', -2), (3, '2017-03-01', -3), (3, '2017-04-01', -4)]

final_result = []

for tup in result:
    tup_added = False
    for current_list in final_result:
        if current_list[0] == tup[1]:
            current_list.append(tup[2])
            tup_added = True
            break
    if not tup_added:
        final_result.append([tup[1], tup[2]])

final_result = [tuple(x) for x in final_result]

print(final_result)

答案 1 :(得分:2)

尝试使用groupby中的itertools

from itertools import groupby

result = []
sub_result= []
for key, group in groupby(a_list, lambda x: x[1]):
    sub_result.append(key)
    for g in group:
        sub_result.append(g[2])
    result.append(tuple(sub_result))
    sub_result = []
print result

输出:

[('2017-01-01', -1, 2, 20), ('2017-02-01', -2, 4, 40), ('2017-03-01', -3, 6, 60), ('2017-04-01', -4, 8, 80)]