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