繁体   English   中英

实现列表/字典理解的 Pythonic 方式

[英]Pythonic way to achieve a list/dict comprehension

比方说,我有一个元组列表:

lst = [('NP', (2, 4)), ('VP', (1, 4)), ('VP', (0, 4)), 
       ('S-SBJ', (0, 4)), ('ADJP-PRD', (5, 7)), ('VP', (4, 7))]

获得以下内容的最标准/pythonic 方式是什么:

out = {(2, 4): 1, (1, 4): 1, (0, 4): 2, (5, 7): 1, (4, 7): 1}

我试着做:

from collections import defaultdict

d = defaultdict(list)
for item in lst:
    d[item[1]].append(item[0])

dct = {}
for k, v in d.items():
    dct[k] = len(v)

print(dct)
# {(2, 4): 1, (1, 4): 1, (0, 4): 2, (5, 7): 1, (4, 7): 1}

我会使用一个Counter

>>> from collections import Counter
>>> lst = [('NP', (2, 4)), ('VP', (1, 4)), ('VP', (0, 4)),
...        ('S-SBJ', (0, 4)), ('ADJP-PRD', (5, 7)), ('VP', (4, 7))]
>>> c = Counter(item[1] for item in lst)
>>> c
Counter({(0, 4): 2, (2, 4): 1, (1, 4): 1, (5, 7): 1, (4, 7): 1})

您可以使用itertools.groupby

from itertools import groupby as gb
lst = [('NP', (2, 4)), ('VP', (1, 4)), ('VP', (0, 4)), ('S-SBJ', (0, 4)), ('ADJP-PRD', (5, 7)), ('VP', (4, 7))]
r = {j:i for _, b in gb(lst, key=lambda x:x[0]) for i, j in enumerate(b, 1)}

Output:

{('NP', (2, 4)): 1, ('VP', (1, 4)): 1, ('VP', (0, 4)): 2, ('S-SBJ', (0, 4)): 1, ('ADJP-PRD', (5, 7)): 1, ('VP', (4, 7)): 1}

如果您正在寻找纯粹的理解:

>>> lst = [('NP', (2, 4)), ('VP', (1, 4)), ('VP', (0, 4)), 
...        ('S-SBJ', (0, 4)), ('ADJP-PRD', (5, 7)), ('VP', (4, 7))]
>>> {tup[1]: sum([1 for itup in lst if itup[1] == tup[1]]) for tup in lst}
{(2, 4): 1, (1, 4): 1, (0, 4): 2, (5, 7): 1, (4, 7): 1}
>>>  

但是上面的理解是相当简洁的。 可读的方式是:

>>> d = {};
>>> for x, y in lst:
...     d[y] = 1 if y not in d else d[y] + 1
... 
>>> d
{(2, 4): 1, (1, 4): 1, (0, 4): 2, (5, 7): 1, (4, 7): 1}
>>> 

然而,OP 的defaultdict解决方案也是可读的; 但我会使用0作为默认值,然后在每次匹配时递增1 这样,您就不需要额外的循环来计算len

我看到的最简单的方法是:

from collections import Counter

d = dict(Counter([i[1] for i in lst]))

它准确地给出了您要求的 output:

{(2, 4): 1, (1, 4): 1, (0, 4): 2, (5, 7): 1, (4, 7): 1}

暂无
暂无

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

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