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})
我有一个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})