Python,如何有效地从列表列表生成嵌套字典
我有一个列表,看起来像这样Python,如何有效地从列表列表生成嵌套字典,python,Python,我有一个列表,看起来像这样 [['ip1',404], ['ip1',200], ['ip1',200], ['ip2',200], ['ip2',200], ['ip2',504]] 我需要做一个字典,有ip地址的状态代码计数 results = {'ip1':{404:1,200:2},'ip2':{200:2,504:1}} >>从集合导入defaultdict >>>d=defaultdict(lambda:defaultdict(int)) >>>ips=[['ip1',404],
[['ip1',404],
['ip1',200],
['ip1',200],
['ip2',200],
['ip2',200],
['ip2',504]]
我需要做一个字典,有ip地址的状态代码计数
results = {'ip1':{404:1,200:2},'ip2':{200:2,504:1}}
>>从集合导入defaultdict
>>>d=defaultdict(lambda:defaultdict(int))
>>>ips=[['ip1',404],'ip1',200],'ip1',200],'ip2',200],'ip2',200],'ip2',504]]
>>>对于ip,ip中的num:
d[ip][num]+=1
>>>d
defaultdict(,{'ip2':defaultdict(,{200:2504:1}),'ip1':defaultdict(,{200:2404:1})
试试这个:
values = [['ip1',404],
['ip1',200],
['ip1',200],
['ip2',200],
['ip2',200],
['ip2',504]]
counts = {}
for value in values:
ip, status_code = value
if ip not in counts:
counts[ip] = {}
if status_code not in counts[ip]:
counts[ip][status_code] = 0
counts[ip][status_code] += 1
{'ip2': {200: 2, 504: 1}, 'ip1': {200: 2, 404: 1}}
它几乎适用于任何python版本。集合中的工具可以很快解决此问题:
>>> from collections import defaultdict, Counter
>>> d = defaultdict(Counter)
>>> for ip, code in [['ip1',404], ['ip1',200], ['ip1',200],
['ip2',200], ['ip2',200], ['ip2',504]]:
d[ip][code] += 1
>>> dict(d)
{'ip2': Counter({200: 2, 504: 1}), 'ip1': Counter({200: 2, 404: 1})}
当提供示例代码时,请至少检查它在语法上是否有效。我修复了它,但在计算意义上这不是很有效。这个答案有效,但defaultdict中的计数器更干净。这现在是我工具包的一部分…我从来不知道它在那里!无需将结果转换为
dict
-defaultdict
/计数器
是dict
的子类,可以直接使用。@astynax我很确定这只是为了查看目的。计数器
很酷-以前从未见过。Python2.7中新增了:@NickCraig-Wood对于使用较旧python的用户,在+1处有一个Py2.5后端口,用于向后兼容dict.setdefault
会缩短代码,并且已经存在了很长时间,文档中没有提到它的引入时间!例如对于ip,值中的状态代码:counts[ip][status\u code]=counts.setdefault(ip,{}).setdefault(status\u code,0)+1
values = [['ip1',404],
['ip1',200],
['ip1',200],
['ip2',200],
['ip2',200],
['ip2',504]]
counts = {}
for value in values:
ip, status_code = value
if ip not in counts:
counts[ip] = {}
if status_code not in counts[ip]:
counts[ip][status_code] = 0
counts[ip][status_code] += 1
{'ip2': {200: 2, 504: 1}, 'ip1': {200: 2, 404: 1}}
>>> from collections import defaultdict, Counter
>>> d = defaultdict(Counter)
>>> for ip, code in [['ip1',404], ['ip1',200], ['ip1',200],
['ip2',200], ['ip2',200], ['ip2',504]]:
d[ip][code] += 1
>>> dict(d)
{'ip2': Counter({200: 2, 504: 1}), 'ip1': Counter({200: 2, 404: 1})}
L = [[ip1,404], [ip1,200], [ip1,200], [ip2,200], [ip2,200], [ip2,504]]
D = {}
for entry in L:
ip = entry[0]
code = entry[1]
ip_entry = D.get(ip, {})
ip_entry[code] = ip_entry.get(code, 0) + 1
D[ip] = ip_entry