首页 > 解决方案 > 为什么我的生成器函数不循环?

问题描述

我正在创建一个 python 生成器来循环一个句子。“这是一个测试”应该返回

this
is
a
test

问题1:下面的实现有什么问题?它只返回“this”并且不循环。如何解决?

def my_sentense_with_generator(sentence):
    index = 0
    words = sentence.split()
    current = index
    yield words[current]
    index +=1

for i in my_sentense_with_generator('this is a test'):
   print(i) 
>> this

问题2:另一种实现方式如下。有用。但我对在这里使用“for”的目的感到困惑。我被教导在一种方式中,使用生成器代替“for循环”,这样python就不必预先构建整个列表,因此它需要更少的内存和时间链接。但是在这个解决方案中,它使用for循环来构造一个生成器..它是否违背了生成器的目的?

def my_sentense_with_generator(sentence):
    for w in sentence.split():
        yield w

标签: pythonpython-3.x

解决方案


生成器的目的不是避免定义循环,而是仅在需要时生成元素(而不是在构造时)

在您的第一个示例中,您还需要生成器中的循环。否则生成器只能生成单个元素,然后它就被耗尽了。

注意。在下面的生成器中,str.split创建了一个列表,因此使用生成器没有内存优势。这可以用迭代器代替iter(sentence.split())

def my_sentence_with_generator(sentence):
    words = sentence.split()
    for word in words:
        yield word

for i in my_sentence_with_generator('this is a test'):
    print(i) 

输出:

this
is
a
test

生成器中的循环定义了生成器的元素,if 将暂停直到有东西请求生成器的元素。因此,您还需要在生成器之外进行一个循环来请求元素。

部分元素集合的示例:

g = my_sentence_with_generator('this is a test')

next(g), next(g)

输出:('this', 'is')

发电机效用的例子:
def count():
    '''this generator can yield 1 trillion numbers'''
    for i in range(1_000_000_000_000_000):
        yield i
     

# we instanciate the generator   
c = count()

# we collect only 3 elements, this consumes very little memory
next(c), next(c), next(c)

推荐阅读