gpt4 book ai didi

python - 恢复 python 生成器的定义表达式

转载 作者:太空宇宙 更新时间:2023-11-04 06:25:07 24 4
gpt4 key购买 nike

给定一个生成器

g = ( <expr> for x in <iter> ),

有什么方法可以恢复用于定义 g 的表达式和迭代器吗?

例如,一个函数的行为如下:

expr, iter = f( ( x*x for x in range(10) ) )
expr(2) # 4
expr(5) # 25
iter[1] # 1
iter[9] # 9
iter[10] # raises IndexError

我想要此功能的原因是我创建了自己的 LazyList 类。我希望它的行为本质上像一个生成器,除了允许通过 getitem 访问而不必在访问第 k 个元素之前迭代 k-1 个元素。谢谢。

编辑:这是惰性列表类的快照:

class LazyList(object):
def __init__(self, iter=None, expr=None):
if expr is None:
expr = lambda i: i
if iter is None:
iter = []
self._expr = expr
self._iter = iter

def __getitem__(self, key):
if hasattr(self._iter, '__getitem__'):
return self._expr(self._iter[key])
else:
return self._iter_getitem(key)

def __iter__(self):
for i in self._iter:
yield self._expr(i)

我省略了 _iter_getitem 方法。所有这些所做的就是遍历 _iter 直到它到达键的第一个元素(或者如果键是一个切片,则使用 itertool 的 islice)。还有常见的 llmap、llreduce 等函数,我已经省略了,但您可能会猜到它们是如何进行的。

我希望能够分解生成器的动机之一是我可以像这样优雅地初始化这个类

l = LazyList(x*x for x in range(10))

代替

l = LazyList(range(10), lambda x: x*x)

但真正的好处是,经过润色,这将是生成器概念的一个很好的概括,并且能够用于代替任何生成器(具有相同的内存节省优势)。

我在 Django 中经常使用它,因为它与他们的查询集配合得很好。我有很多依赖于惰性列表结构的代码,因为它返回多维数组,如果对其进行评估,将获取比我需要的更多的数据。

最佳答案

我能想到的最接近的是反汇编生成器表达式中的代码对象。有点像

>>> import dis>>> g = ( x*x for x in range(10) )>>> dis.dis(g.gi_code)  1           0 LOAD_FAST                0 (.0)        >>    3 FOR_ITER                15 (to 21)              6 STORE_FAST               1 (x)              9 LOAD_FAST                1 (x)             12 LOAD_FAST                1 (x)             15 BINARY_MULTIPLY                  16 YIELD_VALUE                      17 POP_TOP                          18 JUMP_ABSOLUTE            3        >>   21 LOAD_CONST               0 (None)             24 RETURN_VALUE        

这对正在发生的事情提供了一些提示,但不是很清楚,恕我直言。

another Stack Overflow question处理将 Python 字节代码转换为可读的 Python — 也许您可以使用它来获得更易于阅读的内容。

关于python - 恢复 python 生成器的定义表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8864546/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com