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'}]
答案 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]]
当然,如果您选择使用整个列表,则不需要第一行。
我希望这能为你解决这个问题。如果您有其他问题,请与我们联系。