itertools.groupby() 值消失

问题描述

我有一个嵌套列表 [['A','B'],['A','C'],['D'],['C','A']]

import itertools
d = {}
for key,group in itertools.groupby([['A','A']],lambda x: x[0]):
    d[key] = list(group)
print(d)

现在我要{'A': [['A','C']],'D': [['D']],'C': [['C','A']]}

但是,由于 'D' 是唯一具有单个元素的嵌套列表,我希望所有单个元素都打印为数字 0

我想输出{'A': [['A','D': 0,'A']]},所以我添加一个 if-else 子句并将我的代码更改为:

for key,lambda x: x[0]):
    if len(list(group)[0]) > 1:
        d[key] = list(group)
    else: d[key] = 0
print(d)

然而,上面的代码打印出来是{'A': [],'C': []}。我没有发现我的代码有任何问题。但是,为什么 AC 会打印出一个空列表?

解决方法

您看到的问题是在对 list(group) 的调用中对 len 的第一次调用耗尽了 group 指向的迭代器;您只能使用一次。因此,您需要将这些值保存在临时列表中。

你可以这样做:

import itertools 

d = {}
li=[['A','B'],['A','C'],['D'],['C','A']]

for key,group in itertools.groupby(li,lambda x: x[0]):
    gv=list(group)
    if len(gv) > 1:
        d[key] = gv
    else: d[key] = 0
    
print(d)
# {'A': [['A','C']],'D': 0,'C': 0}

你也可以缩短一点:

for key,lambda x: x[0]):
    gv=list(group)
    d[key]=gv if len(gv) > 1 else 0

你问我第一次在哪里使用发电机?

考虑以下示例:

>>> gen=(x*2 for x in (1,2,3))  # a generator expression
>>> type(gen)
<class 'generator'>
>>> list(gen)
[2,4,6]
>>> list(gen)
[]

如果您在生成器上使用 list,则会耗尽生成器。您在 list(group) 内使用了 len,这会耗尽生成器。第二次调用 list -- 什么都没有了。

,

您面临的问题是,当您调用 list(group) 时,您是在强制生成器生成所有元素,因此下次使用它时,它上面没有任何元素。

使用以下内容:

import itertools

d = {}

for key,group in itertools.groupby([['A','A']],lambda x: x[0]):
    group_list = list(group)
    d[key] = group_list if len(group_list[0]) > 1 else 0
print(d)

输出

{'A': [['A','C': [['C','A']]}