Python:如何按类别对这个项目列表进行分组?

时间:2012-08-09 21:04:44

标签: python django

使用Django应用程序。我有一个ads列表,我希望能够在模板中过滤这些内容(例如,抓取spot_id = 1的所有广告,然后选择一个随机广告。

我通过光标使用原始SQL而不是Django的神秘查询,所以我已经有了我的列表(转换为字典)。这是我到目前为止所做的:

# list/dict of ads
[
 {'filename': u'rc_ad_06_02_11.gif', 'spot_id': 1L }, 
 {'filename': u'k_banner.jpg', 'spot_id': 1L}, 
 {'filename': u'dwarves-banner.gif', 'spot_id': 1L}, 
 {'filename': u'k_skyscraper.jpg', 'spot_id': 2L }
]   

# attempt to group them somehow
final_ads = []

    last_spot_id = 0
    for a in ads:
        if a['spot_id'] != last_spot_id:
        final_ads[a['spot_id']][] = a # syntax error here
    last_spot_id = a['spot_id']

logger.info(final_ads)

这不起作用。我本来想要的是这种结构的列表:

[
 1: [
     {'filename': u'rc_ad_06_02_11.gif', 'spot_id': 1L }, 
     {'filename': u'k_banner.jpg', 'spot_id': 1L}, 
     {'filename': u'dwarves-banner.gif', 'spot_id': 1L}
 ],
 2: [
     {'filename': u'k_skyscraper.jpg', 'spot_id': 2L }
 ]
]   

(想不出一种正确的表达方式,抱歉,如果看起来不正确的话)。

如果有人能告诉我一个更聪明的方法,我会非常感激。感谢。

4 个答案:

答案 0 :(得分:2)

defaultdict应该处理好这将返回一个字典而不是列表

final_ads将类似{1:[a1,a3,a4],2:[a2,a5] ...}

from collections import defaultdict
final_ads = defaultdict(list)
for a in ads:
    final_ads[a['spot_id']].append(a)

print final_ads
for spot_id in sorted(final_ads.keys()):
    print "Spot %s=%s"%(spot_id,final_ads[spot_id])

上面的代码与您的dicts 返回打印

列表
defaultdict(<type 'list'>, {1L: [{'spot_id': 1L, 'filename': u'rc_ad_06_02_11.gif'}, {'spot_id': 1L, 'filename': u'k_banner.jpg'}, {'spot_id': 1L, 'filename': u'dwarves-banner.gif'}], 2L: [{'spot_id': 2L, 'filename': u'k_skyscraper.jpg'}]})
Spot 1=[{'spot_id': 1L, 'filename': u'rc_ad_06_02_11.gif'}, {'spot_id': 1L, 'filename': u'k_banner.jpg'}, {'spot_id': 1L, 'filename': u'dwarves-banner.gif'}]
Spot 2=[{'spot_id': 2L, 'filename': u'k_skyscraper.jpg'}]

答案 1 :(得分:1)

我认为这个脚本正是你要找的。

final_ads = {}
for a in ads:
    final_ads.setdefault(a['spot_id'], []).append(a)

注意setdefault初始化列表(如果不存在)。

答案 2 :(得分:1)

import collections
final_ads = collections.defaultdict(list)
for ad in ads:
    final_ads[ad['spot_id']].append(ad)
logger.info(final_ads)

答案 3 :(得分:1)

import itertools
grps = itertools.groupby(ads,lambda x:x['spot_id'])
final_ads = dict(map(lambda (k,g):(k,list(g)),grps)