Python中的函数如何在返回后记住它的值?

时间:2013-04-10 15:22:52

标签: python

警告:极端新手问题

我似乎一直在考虑将功能作为一种配方。在我的世界中,程序是一个食谱盒,一些食谱(功能)需要其他食谱(其他功能)。处理器通过将指令写入RAM并通过它们来开始执行主配方。喜欢,早餐薄饼。你叫Julia Childs的早餐薄饼食谱。你必须做一次绉面糊。然后,当你还有绉面糊时,你会反复制作绉纱。同时,您可以制作各种水果制品。

好吧,我显然不明白。我只是通过pythontutor.com运行python wiki解决方案到Project Euler Problem 2(甚至Fibonacci数字总和不到400万)。我觉得有些事发生在我身上。看起来每次你召唤一个食谱,你不只是使用相同的处理器,你会得到一个带有一些罐子的侏儒来处理这个功能。底池是变量,gnome计算出他的配方,如果调用函数期望返回值,gnome会向调用者显示这些底池的内容。然后调用者可以返回,找出更多的东西,并向他的调用者显示返回值。

让我们说Al打电话给Bob制作薄饼。鲍勃做了击球手并打电话给查理做饭。查理做了一个绉纱,为鲍勃提供绉纱,鲍勃把它送给艾尔,然后回到查理。谁还存在! Al不知道鲍勃有查理藏在厨房里,但即使在查理制作第一个绉纱之后,他仍然在厨房里,知道如何制作绉纱,并且知道他留下了多少绉纱面糊。即使他已经退回了第一个绉纱。

有人可以帮我解决这个问题吗?

这是Python wiki的代码

 def fib():
    x,y = 0,1
    while True:
        yield x
        x,y = y, x+y

def even(seq):
    for number in seq:
        if not number % 2:
            yield number

def under_a_million(seq):
    for number in seq:
        if number > 1000000:
            break
        yield number   

print sum(even(under_a_million(fib())))

这里是http://pythontutor.com/visualize.html

3 个答案:

答案 0 :(得分:3)

简化答案。

如果您有一个生成一系列值的函数,您可以使用yield在generator中对其进行转换。

def func():
    for i in range(3):
        yield i

list(func()) ==> [0,1,2]

for el in func():
    print(el) # 0
              # 1
              # 2

每次调用yield时,函数都会被冻结。当它再次被调用时,它会从最后一个状态继续,并且不会重新开始(除非它已经完成消耗元素)。

如果您调用该函数,则会得到generator,这是您可以迭代的内容。

请注意,这样您可以迭代无限序列而无需使用无限内存。

def inf():
    x = -1
    while True:
        x = x + 1
        yield x

for i in inf():
    if i < 10:
        print(i)
    else:
        break

答案 1 :(得分:2)

这是因为那些函数不是函数,而是generators。  yield语句返回一个值,但不从函数返回。每次在生成器上调用next时,它会从上次调用继续执行生成器,直到它再次到达yield语句。

答案 2 :(得分:1)

原则上你的第一个假设是正确的:函数的变量仅在执行函数时可用。但是,在您的情况下,您使用的是yield语句。因此,函数调用返回一个迭代器,当调用它时,它返回下一个yield语句的值。

检查this post以获取有关迭代器的内容和操作的进一步说明。