Python如何根据属性在对象上使用Counter

时间:2015-02-03 19:01:22

标签: python sorting object attributes counter

我有一个名为record的类,它存储日志记录的信息;

class Record():
    def __init__(self, **kwargs):
        for key, value in kwargs.items():
             setattr(self, key, value)

此记录的例子可以是:

r1 = Record(uid='001',url='www.google.com',status=200)
r2 = Record(uid='002',url='www.google.com',status=404)
r3 = Record(uid='339',url='www.ciq.com', status=200)
...

我想要的是计算每个网址有多少用户。所以对于“google”,有'001'和'002'。我通常使用计数器来记录列表中的元素及其外观。但在这里,Counter似乎只是放置元素而不是计算它们。我可以放一个lambda还是试试?

我可以通过所有工作人员......

我想我可能会在这里引起混淆。

我的关键点是按对象的属性对对象进行分组......所以不仅要计算网址,还需要

res = Counter(r)

(不知道怎么把lambda放在里面甚至可能)我可以得到

res[0].url = 'www.google.com'

它的数量是2 ..?

并建议?

谢谢!

2 个答案:

答案 0 :(得分:1)

您应该能够遍历所有记录并将url值传递给Counter,如下所示:

records = [r1, r2, r3, ...]
url_counter = Counter(r.url for r in records)
print(url_counter['www.google.com'])

答案 1 :(得分:0)

我之前的回答中有一个微妙的错误,在修复它时,我提出了一种更简单,更快捷的方法来处理不再使用itertools.groupby()的事情。

下面更新的代码现在具有一个专门用于完成您想要的功能。

from collections import Counter
from operator import attrgetter

class Record(object):
    def __init__(self, **kwargs):
        for key, value in kwargs.iteritems():
             setattr(self, key, value)

records = [Record(uid='001', url='www.google.com', status=200),
           Record(uid='002', url='www.google.com', status=404),
           Record(uid='339', url='www.ciq.com',    status=200)]

def count_attr(attr, records):
    """ Returns Counter keyed by unique values of attr in records sequence. """
    get_attr_from = attrgetter(attr)
    return Counter(get_attr_from(r) for r in records)

for attr in ('status', 'url'):
    print('{!r:>8}: {}'.format(attr, count_attr(attr, records)))

输出:

'status': Counter({200: 2, 404: 1})
   'url': Counter({'www.google.com': 2, 'www.ciq.com': 1})