Python Group通过字典数组中的多个键

时间:2015-01-08 20:42:56

标签: python django python-2.7 group-by

我在Python中有一个像这样的字典数组

{'district': u'd1', 'community': u'commu2', 'month': 8.0, 'county': u'c1', 'year': 2012.0, 'organization': u'org1'}
{'district': u'd2', 'community': u'commu8', 'month': 9.0, 'county': u'c1', 'year': 2012.0, 'organization': u'org2'}
{'district': u'd1', 'community': u'commu4', 'month': 9.0, 'county': u'c1', 'year': 2012.0, 'organization': u'org1'}
{'district': u'd2', 'community': u'commu5', 'month': 8.0, 'county': u'c1', 'year': 2012.0, 'organization': u'org2'}
{'district': u'd2', 'community': u'commu7', 'month': 9.0, 'county': u'c1', 'year': 2012.0, 'organization': u'org2'}
{'district': u'd1', 'community': u'commu3', 'month': 9.0, 'county': u'c1', 'year': 2012.0, 'organization': u'org1'}
{'district': u'd2', 'community': u'commu6', 'month': 8.0, 'county': u'c1', 'year': 2012.0, 'organization': u'org2'}
{'district': u'd1', 'community': u'commu1', 'month': 8.0, 'county': u'c1', 'year': 2012.0, 'organization': u'org1'}

如何按多个键值进行分组,例如(区,月,年,组织)并生成这样的非规范化列表?

{'district': u'd1', 'organization': u'org1', 'month': 8.0, 'county': u'c1', 'year': 2012.0, 'community': ['commu1', 'commu2']}
{'district': u'd1', 'organization': u'org1', 'month': 9.0, 'county': u'c1', 'year': 2012.0, 'community': ['commu3', 'commu4']}
{'district': u'd2', 'organization': u'org2', 'month': 9.0, 'county': u'c1', 'year': 2012.0, 'community': ['commu5', 'commu6']}
{'district': u'd2', 'organization': u'org2', 'month': 8.0, 'county': u'c1', 'year': 2012.0, 'community': ['commu7', 'commu8']}

编辑:我感兴趣的数据库TABLE列是

DISTRICT, COMMUNITY, DATE, ORGANIZATION, COMMUNITY

我正在使用Django的ORM以如上所述的格式1获取数据,但我确实需要格式为2的数据

我的Django ORM fetch看起来像这样

list(ActivityReport.objects.all().
     values('date').\
    extra(select={'year': "EXTRACT(year FROM date)"}).\
    extra(select={'month': "EXTRACT(month FROM date)"}).\
     values('organization' ,'year','month', 'district', 'community'))

我的Django模型看起来像这样

class MyModel(models.Model):
    organization = models.CharField(max_length=200)
    district = models.CharField(max_length=200)
    community = models.CharField(max_length=200, null=True)
    date = models.DateField(default=datetime.date.today)

1 个答案:

答案 0 :(得分:1)

在我们的discussion in chat之后,我们知道这里有一些额外的限制:进入的数据采用这种格式,它按原样保存到数据库中,并且建议的解决方案是迭代它来按摩它在将其提供给用户之前查看处理。

如果社区是外键关系,那么在性能方面可能会更好,以反映它是一对多的,因此这可能不是最具扩展性的解决方案。注意事项,这就是我的建议:

>>> # data is your original dict
>>> output = {}
>>> for row in data:
...   key = (row['month'], row['year'], row['district'], row['organization'])
...   if key in output:
...     output[key].append(row['community'])
...   else:
...     output[key] = [row['community']]
... 
>>> output
{(9.0, 2012.0, u'd1', u'org1'): [u'commu4', u'commu3'], (8.0, 2012.0, u'd2', u'org2'): [u'commu5', u'commu6'], (9.0, 2012.0, u'd2', u'org2'): [u'commu8', u'commu7'], (8.0, 2012.0, u'd1', u'org1'): [u'commu2', u'commu1']}

这里的想法是使用一对一数据作为元组,它是不可变的,因此可以作为dict键,然后创建从该列表到社区列表的映射。如果映射已经存在,则附加到列表,否则创建它。一次通过后,数据如图所示。

希望如果存在其他一对多关系,这种技术可以适应真实数据集甚至其他列表。