重用生成器表达式 [英] Reusing generator expressions

查看:105
本文介绍了重用生成器表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

生成器表达式是一个非常有用的工具,相对于列表推导,它具有巨大的优势,因为列表推导不会为新数组分配内存.

Generator expressions is an extremely useful tool, and has a huge advantage over list comprehensions, which is the fact that it does not allocate memory for a new array.

生成器表达式所面临的问题最终使我最终不得不写列表推导式,因为我只能使用一次这样的生成器:

The problem I am facing with generator expressions, which eventually makes me end up writing list comprehensions, is that I can only use a such a generator once:

>>> names = ['John', 'George', 'Paul', 'Ringo']
>>> has_o = (name for name in names if 'o' in name)
>>> for name in has_o:
...   print(name.upper())
...
JOHN
GEORGE
RINGO
>>> for name in has_o:
...   print(name.lower())
...
>>>

上面的代码说明了生成器表达式只能使用一次.那当然是因为生成器表达式返回生成器的实例,而不是定义可以一次又一次实例化的生成器函数.

The above code illustrates how the generator expression can only be used once. That's of course, because the generator expression returns an instance of the generator, rather than defining a generator function which could be instantiated again and again.

是否有一种方法可以在每次使用生成器时对其进行克隆,以使其可重用,或者使生成器表达式的语法返回生成器函数而不是单个实例?

Is there a way to clone the generator each time it is used, in order to make it reusable, or to make the generator expressions syntax return a generator function rather than a single instance?

推荐答案

将其设为lambda:

has_o = lambda names: (name for name in names if 'o' in name)
for name in has_o(["hello","rrrrr"]):
   print(name.upper())
for name in has_o(["hello","rrrrr"]):
   print(name.upper())

lambda是单线的,每次返回一个新的生成器.在这里,我选择能够传递输入列表,但是如果它是固定的,则您甚至不需要参数:

lambda is a one-liner and returns a new generator each time. Here I chose to be able to pass the input list, but if it's fixed, you don't even need a parameter:

names = ["hello","rrrrr"]
has_o = lambda: (name for name in names if 'o' in name)
for name in has_o():
   print(name.upper())
for name in has_o():
   print(name.upper())

在最后一种情况下,请注意以下事实:如果names更改或重新分配,则lambda使用新的names对象.您可以使用默认值技巧来修复名称重新分配:

In that last case, be careful about the fact that if names changes or is reassigned, the lambda uses the new names object. You can fix the name reassigning by using the default value trick:

has_o = lambda lst=names: (name for name in lst if 'o' in name)

,您可以使用默认的值和复制"技巧来修复names的后续修改(当您认为您的首要目标是避免创建列表时,它不是超级有用:)):

and you can fix the afterwards modification of names by using the default value-and-copy trick (not super-useful when you think your first goal was to avoid a list to be created :)):

has_o = lambda lst=names[:]: (name for name in lst if 'o' in name)

(现在选择:))

这篇关于重用生成器表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆