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

Python how to use Counter on objects according to attributes

我有一个class命名的记录,它存储了日志记录的信息;

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)
...

我想要的是统计每个url有多少用户。所以对于 "google",有 '001' 和 '002'。我通常使用 Counter 来记录列表中的元素及其外观。但在这里,Counter 似乎只是放置元素,而不是对它们进行计数。有没有我可以输入或尝试的 lambda?

虽然我可以通过所有员工...

我想我在这里可能会造成混淆。

我的重点是根据对象的属性对对象进行分组...所以不仅 url 计数而且

res = Counter(r)

(不知道如何将 lambda 放入其中,甚至是可能的)我可能会得到

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

它的计数是 2..?

还有建议?

谢谢!

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

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

我之前的回答中有一个细微的错误,在修复它时我想出了一种更简单、更快捷的方法来做不再使用 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})