python错误:位于0x02DAC198的生成器对象P

2024-05-08 12:04:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我使用的是Python 3.4.*并尝试执行以下代码:

def P(n):
    if n == 0:
        yield []
        return

    for p in P(n-1):        
        p.append(1)
        yield p
        p.pop()
        if p and (len(p) < 2 or p[-2] > p[-1]):
            p[-1] += 1
            yield p


print(P(5))   # this line doesn't make sense


for i in P(5):   # but this line does make sense thanks to furkle 
    print(i) 

但是我得到的是<generator object P at 0x02DAC198>,而不是输出。在

有人能解释一下我的代码在哪里需要修正吗?我不认为py喜欢函数名P,但我可能错了。在

编辑:furkle澄清了<generator object P at 0x02DAC198>。在

顺便说一句,我现在正在写我自己修改的配分函数,我试图理解这个与经典设置相对应的配分函数。在


Tags: 代码informakeifobjectlinethis
3条回答

这段代码有很多问题,以及您对生成器如何工作以及它们的用途的理解都有问题。在

首先,对于您的print语句,这正是它应该打印的内容。生成器从不隐式扩展,因为不能保证生成器会终止。构造一个生成无止境序列的生成器是完全有效的,有时也是非常可取的。为了得到您想要的结果(我假设是生成类似于列表的输出),您可以:

print(list(P(5))

但这又引出了我的第二点:生成器在序列中产生值(99%的用法都是这样,除非你把它作为协程函数使用)。您正试图使用生成器构造一个列表;但是,如果n不是0,那么这将永远不会产生值并立即返回。如果您的目标是构建一个生成器,该生成器生成一个给定长度的1的列表,那么它应该如下所示:

^{pr2}$

这将产生一个长度为n的序列。要获得列表表单,您需要做list(P(n))。在

{我建议你换一个更好的工具。在

在阅读函数时,我试图找出调用将产生什么结果。让我们从完整的原始代码开始:

def P(n):
    if n == 0:
        yield []
        return

    for p in P(n-1):        
        p.append(1)
        yield p
        p.pop()
        if p and (len(p) < 2 or p[-2] > p[-1]):
            p[-1] += 1
            yield p


print(P(5))   # this line doesn't make sense

好的,它调用P(5)。因为那不是0,P递归,直到我们到达P(0),它产生一个空列表。这是p第一次收到值。然后P(1)1追加到该列表中,并将其交给P(2),后者将重复该过程。。等等。所有相同的列表,最初由P(0)创建,最终由P(5)生成[1,1,1,1,1],但随后奇迹发生了。让我们把这个第一个列表称为l0。在

当您向生成器请求第二项时,control返回到P(5),它现在从l0中删除一个值。根据一系列条件,它可能会增加最后一个值并再次生成p,也就是l0。所以我们收到的第一件商品在我们要求第二件商品的时候一直在变。这最终将终止,但意味着这两者之间存在差异:

^{pr2}$

这就是为什么我把它称为post modification;它返回的值在产生之后会不断变化(因为它们实际上是被操纵的同一个对象)。在

我想你误解了发电机的概念。生成器对象类似于一个列表,但是您可以懒洋洋地迭代其结果,而不必等待整个列表的构造。对返回生成器的函数调用操作不会对生成器生成的每个项按顺序执行该操作。在

如果要打印p(5)的所有输出,则应写下:

for i in P(5):
    print(i)

如果您只想打印生成器返回的内容的列表,这在很大程度上似乎违背了生成器的用途。在

相关问题 更多 >