python字典编码_python 可分组字典

class Person(object):

def __init__(self,first_name,last_name):

self.first_name =first_name

self.last_name = last_name

def __repr__(self):

return u"first name :" + unicode(self.first_name) \

+ u" ; last name :" + unicode(self.last_name)

a1 = [Person(u"liu", u"xing"), Person(u"liu", u"xu"), Person(u"zhang", u"xing")]

a2 = [Person(u"liu", u"qin"), Person(u"li", u"jun"), Person(u"zhang", u"hua")]

使用python 开发时,是不是时常有这样的需求,对一个集合的每个对象,按照某属性分类,比如

需要按照姓来分组,同姓的分在一个组内。大伙比较常见的做法如下:

d = {}

for per in a1:

if per.first_name not in d:

d[per.first_name] = []

d[per.first_name].append(per)

for per in a2:

if per.first_name not in d:

d[per.first_name] = []

d[per.first_name].append(per

python中对dict的默认值有设置,详见python doc的dict.setdefault

d = {}

for per in a1:

d.setdefault(per.first_name, []).append(per)

for per in a2:

d.setdefault(per.first_name, []).append(per)

python提供自动创建默认值的结构defaultdict

进一步优化,如下:

d = defaultdict(list)

for per in a1:

d[per.first_name].append(per)

for per in a2:

d[per.first_name].append(per)

熟悉列表推导或者map方法的进一步优化:

d = defaultdict(list)

map(lambda per:d[per.first_name].append(per),a1)

map(lambda per:d[per.first_name].append(per),a2)

d = defaultdict(list)

[d[per.first_name].append(per) for per in a1]

[d[per.first_name].append(per) for per in a2]

还有进一步优化的可能吗?熟悉reduce的朋友可以看下我提供的解决方案,代码如下:

class GroupDict(defaultdict):

def __init__(self, default_factory=list):

'''

@param default_factory: default value generator

'''

super(GroupDict, self).__init__(default_factory)

default_value_type = default_factory if default_factory else list

if issubclass(default_value_type, list) :

self._add_function = default_value_type.append

elif issubclass(default_value_type, set):

self._add_function = default_value_type.add

def append_2_value_collection(self, k, value):

'''

@param k: the key

@param value: the value to add to self[k]

@return: self

@attention: it's important to return self

'''

self._add_function(self[k], value)

return self

那有了这个类,和reduce配合起来就可以像使用jQuery一样链式编写代码了

d = reduce(lambda d, per:d.append_2_value_collection(per.first_name, per), a1, GroupDict())

reduce(lambda d, per:d.append_2_value_collection(per.first_name, per), a2 , d)

for k,v in d.iteritems():

print k ,u"...."

for per in v:

print per

输出结果和上述前几个完全一致。该结构完全继承了dict的功能,只有一个需要注意的,就是一旦使用继承下的方法修改value为非default_factory实例后,再次调用append_2_value_collection将抛异常。请朋友们进一步完善。

0

2

分享到:

sina.jpg

tec.jpg

2012-07-01 00:44

浏览 6540

评论

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值