首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >我能记住一个Python生成器吗?

我能记住一个Python生成器吗?
EN

Stack Overflow用户
提问于 2010-12-31 06:30:35
回答 3查看 4.9K关注 0票数 23

我有一个名为runquery的函数,它调用数据库,然后一个接一个地生成行。我写了一个memoize装饰器(或者更准确地说,我只是从this stackoverflow question那里偷来了一个),但在随后的调用中,它只会产生一个空序列,可能是因为生成器的值只能生成一次。

如何修改适用于Python生成器的memoization装饰器?我意识到在某些时候我需要将它存储在内存中,但我希望在装饰器中处理这个问题,而不是修改原始函数。

memoization函数的当前代码为:

代码语言:javascript
复制
def memoized(f):
    # Warning: Doesn't work if f yields values
    cache={}
    def ret(*args):
        if args in cache:
            return cache[args]
        else:
            answer=f(*args)
            cache[args]=answer
            return answer
    return ret
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-05-24 03:11:16

我意识到这是一个老问题,但对于那些想要完整解决方案的人来说:这里有一个,基于jsbueno的建议:

代码语言:javascript
复制
from itertools import tee
from types import GeneratorType

Tee = tee([], 1)[0].__class__

def memoized(f):
    cache={}
    def ret(*args):
        if args not in cache:
            cache[args]=f(*args)
        if isinstance(cache[args], (GeneratorType, Tee)):
            # the original can't be used any more,
            # so we need to change the cache as well
            cache[args], r = tee(cache[args])
            return r
        return cache[args]
    return ret
票数 20
EN

Stack Overflow用户

发布于 2010-12-31 06:53:43

代码语言:javascript
复制
from itertools import tee

sequence, memoized_sequence = tee (sequence, 2)

好了。

这对于生成器来说更容易,因为标准库有这个"tee“方法!

票数 10
EN

Stack Overflow用户

发布于 2010-12-31 06:33:56

是。有一个装饰师张贴着here。请注意,正如海报所说,您失去了懒惰评估的一些好处。

代码语言:javascript
复制
def memoize(func):
    def inner(arg):
        if isinstance(arg, list):
            # Make arg immutable
            arg = tuple(arg)
        if arg in inner.cache:
            print "Using cache for %s" % repr(arg)
            for i in inner.cache[arg]:
                yield i
        else:
            print "Building new for %s" % repr(arg)
            temp = []
            for i in func(arg):
                temp.append(i)
                yield i
            inner.cache[arg] = temp
    inner.cache = {}
    return inner


@memoize
def gen(x):
    if not x:
        yield 0
        return

    for i in xrange(len(x)):
        for a in gen(x[i + 1:]):
            yield a + x[0]


print "Round 1"
for a in gen([2, 3, 4, 5]):
    print a

print
print "Round 2"
for a in gen([2, 3, 4, 5]):
    print a
票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4566769

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档