如何创建具有某些特定值的行为的字典

时间:2012-07-31 11:33:02

标签: python dictionary

假设我有两个列表:

l1 = [['b', (1, 1)], ['b', (1, 2)], ['b', (1, 3)], ['a', (1, 5)],
      ['b', (2, 1)], ['b',(3, 1)]]

l2 = ['A','B','C']

如何以这种格式创建字典?

dct = {'A': len(sublist1), 'B': len(sublist2), 'C' : len(sublist3)}

,其中

sublist1 = [['b', (1, 1)], ['b', (1, 2)], ['b', (1, 3)], ['a', (1, 5)]]
sublist2 = [['b', (2, 1)]]
sublist3 = [['b',(3, 1)]]

如果我的l1如下所示会发生什么:

ls1 = [[(1, 1), (1, 2), (1, 3), (1, 4), (2, 1), (2, 2)]]    

然后我的输出应该是:

dct = {'A': len(sublist1), 'B': len(sublist2)}

,其中

sublist1 = [[(1, 1),(1, 2),(1, 3),(1, 4)]]
sublist2 = [[(2, 1),(2, 2),(2, 3)]]

整体问题能否以通用方式解决?

5 个答案:

答案 0 :(得分:8)

这似乎有效:

from itertools import groupby

key = lambda x: x[1][0]
lens = [len(list(g)) for k, g in groupby(sorted(l1, key=key), key=key)]
dct = dict(zip(l2, lens))

我希望我假设A匹配1,B匹配2,等等,推断正确。

重新:OP编辑

我不知道(2, 3)中的sublist2项来自何处,我认为这是一个错误。此外,我假设单个元素列表ls1实际上意味着是元组的直接容器,因为这里使用嵌套列表没有任何意义。如果是这样,这是我对通用解决方案的建议:

from itertools import groupby
from string import ascii_uppercase

key = lambda x: x[0]
lens = [len(list(g)) for k, g in groupby(sorted(l1, key=key), key=key)]
dct = dict(zip(ascii_uppercase, lens))

所以,没有太大的变化。 zip函数在给定长度不等的参数时,将返回一个与最短参数长度相同的列表,在这种情况下,这种行为很适合我们。

请记住,如果第一个元组元素的值超过26个,那么此解决方案将会中断,并且只是忽略任何大于26的值。

答案 1 :(得分:1)

groups = itertools.groupby(l1, lambda x: x[1][0])
dict(zip(l2, map(len, (list(list(g[1]) for g in groups)))))

结果

{'A': 4, 'B': 1, 'C': 1}

答案 2 :(得分:0)

>>> l1 = [['b', (1, 1)], ['b', (1, 2)], ['b', (1, 3)], ['a', (1, 5)], ['b', (2,
1)], ['b',(3, 1)]]
>>> dct = {'A': 0, 'B' : 0, 'C': 0}
>>> translation = {1: 'A', 2: 'B', 3: 'C'}
>>> for list_ in l1:
...     letter, tuple_ = list_
...     num1, num2 = tuple_
...     t = translation[num1]
...     dct[t] += 1
...
>>> dct
{'A': 4, 'C': 1, 'B': 1}

答案 3 :(得分:0)

from collections import defaultdict

lst = [['b', (1, 1)], 
       ['b', (1, 2)],
       ['b', (1, 3)],
       ['a', (1, 5)],
       ['b', (2, 1)],
       ['b', (3, 1)]]  #test list

def mapping(x):
    """ convert 1 to A, 2 to B and so on """
    return chr(ord('A')+x-1)

dct = defaultdict(int)

for _, tple in lst:
    k, _ = tple
    dct[ mapping(k) ] += 1

print (dct) # defaultdict(<type 'int'>, {'A': 4, 'C': 1, 'B': 1})

答案 4 :(得分:-1)

我会这样做的:

dct = dict((k, len([l for l in l1 if l[1][0] == i + 1]))
           for i, k in enumerate(l2))