0

我尝试在字典上使用嵌套生成器理解,并将列表作为存储值,并观察到以下奇怪的(对我而言)行为:

Python 2.6.5 (r265:79063, Oct  1 2012, 22:07:21) 
[GCC 4.4.3] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> dummy = {1:[1,2,3],2:[2,3,4],3:[3,4,5]}
>>> a = (d for _,d in dummy.iteritems())
>>> a.next()
[1, 2, 3]
>>> a.next()
[2, 3, 4]
>>> a.next()
[3, 4, 5]
>>> a.next()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration

这是有道理的。接下来的事情没有(至少对我而言)

>>> aa = (dd for dd in (d for _,d in dummy.iteritems()))
>>> aa.next()
[1, 2, 3]
>>> aa.next()
[2, 3, 4]
>>> aa.next()
[3, 4, 5]
>>> aa.next()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration

为什么我的(尝试的)嵌套生成器理解的行为方式与非嵌套版本相同?我本来希望每个 aa.next() 给出一个元素结果,而不是一个列表。

4

3 回答 3

1

您的内部生成器每次迭代时都会返回一个值,并且每个值都是一个列表。您将需要使用实际的嵌套结构。

>>> aa = (d3 for dd in (d for _,d in dummy.iteritems()) for d3 in dd)
>>> next(aa)
1
>>> next(aa)
2
>>> next(aa)
3
>>> next(aa)
2
>>> next(aa)
3
>>> next(aa)
4
>>> next(aa)
3
>>> next(aa)
4
>>> next(aa)
5
>>> next(aa)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
StopIteration
于 2012-10-09T01:56:15.907 回答
1

要获得嵌套,您不需要内部生成器。相反,使用普通的嵌套 for 循环:

>>> dummy = {1:[1,2,3],2:[2,3,4],3:[3,4,5]}
>>> aa = (dd for _,d in dummy.iteritems() for dd in d)
>>> list(aa)
[1, 2, 3, 2, 3, 4, 3, 4, 5]

这将与以下内容相同:

def aa(dummy):
    for _, d in dummy.iteritems():
        for dd in d:
            yield dd

print list(aa())

学习生成器表达式的最佳方法是从普通生成器开始,这样您就可以轻松查看每一步的结果。

于 2012-10-09T01:58:46.827 回答
0

正如您正在考虑的那样,这并不是真正的“嵌套”生成器。

您的代码(大致)相当于:

for dd in (d for _,d in dummy.iteritems()):
    print dd

通常,“嵌套”用于表示以下内容:

(dd for _, d in dummy.iteritems() for dd in d)
于 2012-10-09T01:54:23.130 回答