合并一些列表并将它们重新组合成字典以绘制到多系列Highcharts

时间:2015-10-10 03:03:40

标签: python list dictionary highcharts

animal = ['Hamster', 'Dolphin', 'Ant', 'Hamster', 'Hamster', 'Ant']
date = [20151007, 20151007, 20151007, 20141007, 20120101, 20010101]
total = [27, 5, 5, 5, 18, 40]

我想将这3个列表合并为一个。但如果动物是相同的,它应该组合在一起,总数应该按照日期。如果动物类型没有足够的日期,它将变为0.例如:

[{'name': 'Hamster', 'data': [0, 18, 5, 27]}, 
{'name': 'Dolphin', 'data': [0, 0, 0, 5]}, 
{'name': 'Ant', 'data': [40, 0, 0, 5]}]

我试图将它们绘制到Highcharts 日期列在自己的列表中。

[20010101, 20120101, 20141007, 20151007] 

我可以使用以下方法将列表组合在一起:

zip(animal, date, total)

但如何让他们进入自己的类型并按asc日期安排总数?

编辑

这就是我到目前为止的方式。 我觉得它不高效。 你怎么看?建议有什么改进吗? (只有pythonic建议请)

b = []
for k, v in enumerate(animal):
    counter = 0
    for i in range(len(b)):
        try:
            if b[i]['name'] == v:
                b[i]['data'].append((date[k], total[k]))
                counter = counter + 1
        except KeyError:
            continue
    if counter == 0:
        b.append({'name': v,  'data': [(date[k], total[k])]})

test = set(date)

for k, v in enumerate(list(OrderedDict.fromkeys(animal))):
    for x in test:
        try:
            for i in range(len(test)):
                if b[k]['data'][i][0] == x:
                    break
        except IndexError:
            b[k]['data'].append((x, 0))
    b[k]['data'].sort(key=itemgetter(0))
    temp = [x[1] for x in b[k]['data']]
    b[k]['data'] = []
    b[k]['data'] = temp

结果:

[{'data': [0, 18, 5, 27], 'name': 'Hamster'}, 
{'data': [0, 0, 0, 5], 'name': 'Dolphin'}, 
{'data': [40, 0, 0, 5], 'name': 'Ant'}]

1 个答案:

答案 0 :(得分:1)

我想你想要这样的东西:

animals = ['Hamster', 'Dolphin', 'Ant', 'Hamster', 'Hamster', 'Ant']
dates = [20151007, 20151007, 20151007, 20141007, 20120101, 20010101]
totals = [27, 5, 5, 5, 18, 40]
readings = list(zip(animals, dates, totals))
dates = set(dates)
data = dict()
for animal in animals:
    data[animal] =  {(date, total) for (x, date, total) in readings if x == animal}
    missingDates = dates - {d[0] for d in data[animal] }
    data[animal] |= {(date, 0) for date in missingDates} 

此时,data

{'Dolphin':{(20120101,0),(20151007,5),(20141007,0),(20010101,0)},'Hamster':{(20151007,27),(20141007,5) ,(20120101,18),(20010101,0)},'Ant':{(20120101,0),(20151007,5),(20141007,0),(20010101,40)}}

你需要将它拆开并按日期对每只动物的数据进行排序。我希望这会有所帮助。

编辑这是我承诺的进一步解释。不幸的是,我无法同时看到您的评论和编辑屏幕;我希望我回答你提出的所有观点。在将三个列表压缩在一起之后,我们需要提取每个动物的数据。

右侧的表达方式
data[animal] =  {(date, total) for (x, date, total) in readings if x == animal}

是一种集合理解,它为我们提供了与特定动物相关的所有(日期,总数)对的集合。现在我们需要找到缺少的日期。 我使用了设置差异:

missingDates = dates - {d[0] for d in data[animal] }  

这就是为什么我使用sets:能够简洁地写出缺失日期的表达式。相反,我可以使用列表:

data[animal] = [(date, total) for (x, date, total) in readings if x == animal]
missingDates = [d for d in dates if d not in [d[0] for d in data[animal]]

如果我这样做了,我就不需要早先的陈述

dates = set(dates) 

但是我想避免对missingDates进行复杂的表达,我不想写

presentDates = [d[0] for d in data[animal] 
missingDates = [d for d in dates if d not in presentDates]

现在我必须为缺少的日期添加对(日期,0)。如果我使用过列表,我会写

data[animal] += [(date, 0) for date in missingDates] 

但没有为集合定义+操作;我需要使用工会。 (两个集合的并集是属于两个集合中至少一个集合的元素集。)并集操作表示为|。你是正确的,它可以表示按位或两个整数,但它也可以表示其他操作,就像+可能意味着添加数字或连接列表一样。所以:

data[animal] |= {(date, 0) for date in missingDates}

如果您对套装感到不舒服,请务必使用列表,但您应该了解套装。它们非常有用。

为了继续我之前写过的观点,你现在需要按日期对数据[animal]进行排序。在这里,我们必须更改回列表,因为集合未排序。

data[animal] = list(data[animal])
data[animal].sort()
data[animal] = [d[1] for d in data[animal]]

当然,如果您选择使用整个列表,则不需要第一行。

我希望这能为你解决这个问题。如果您有其他问题,请与我们联系。