简体   繁体   English

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

[英]How to create a dictionary with certain specific behaviour of values

Suppose I have two lists: 假设我有两个列表:

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

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

How can I create a dictionary into this format? 如何创建这种格式的字典?

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

where 哪里

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

what will happen if my l1 is as given below: 如果我的l1如下所示会发生什么:

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

then my output should be: 然后我的输出应该是:

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

where 哪里

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

Can the overall problem can be solved in generic way? 整体问题能否以通用方式解决?

This seems to work: 这似乎有效:

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

I hope I've inferred correctly when I've assumed A match with 1, B with 2, and so on. 当我假设A匹配1时,我希望我推断正确,B代表2,依此类推。

Re: OP edit 回复:OP编辑

I don't know where the (2, 3) item in your sublist2 comes from, I assume it's a mistake. 我不知道子列表(2, 3)中的(2, 3)项来自sublist2 ,我认为这是一个错误。 Also, I assume the single element list ls1 was in fact meant to be the direct container of the tuples, since using nested lists here serves no purpose. 此外,我假设单个元素列表ls1实际上意味着是元组的直接容器,因为这里使用嵌套列表没有任何意义。 If so, here's my proposal for a generic solution: 如果是这样,这是我对通用解决方案的建议:

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

So, no big changes. 所以,没有大的变化。 The zip function will, when given arguments of unequal length, return a list with the same length as the shortest argument, and this behaviour suits us fine in this situation. 当给定长度不等的参数时, zip函数将返回一个与最短参数长度相同的列表,这种行为在这种情况下适合我们。

Keep in mind that if there are more than 26 different values of the first tuple element, then this solution will break, and simply disregard any values larger than the 26th. 请记住,如果第一个元组元素的值超过26个,那么此解决方案将会中断,并且只是忽略任何大于26的值。

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

results in 结果是

{'A': 4, 'B': 1, 'C': 1}
>>> 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}
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})

I would have done this : 我会这样做的:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM