4

假设我有两个列表:

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

可以用通用的方式解决整体问题吗?

4

5 回答 5

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 个的值。

于 2012-07-31T11:43:57.120 回答
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}
于 2012-07-31T11:45:08.513 回答
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}
于 2012-07-31T11:46:35.363 回答
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})
于 2012-07-31T11:52:23.230 回答
-1

我会这样做:

dct = dict((k, len([l for l in l1 if l[1][0] == i + 1]))
           for i, k in enumerate(l2))
于 2012-07-31T11:48:23.473 回答