python中使用生成器

生成器在Python中用于处理大量数据,避免一次性占用内存。由列表推导式转换成生成器生成式,通过()`括号替代`[]`创建。详细创建可通过函数定义,使用`yield`关键字暂停和恢复执行。生成器在需要时生成元素,如`g_num`函数调用产生生成器,通常用for循环迭代而不是手动调用next()。
摘要由CSDN通过智能技术生成

生成器

通过列表,可以包含很多很多的元素,但是受到内存的制约,列表的内容一定是有限的。它无法表达无限的内容。比如说,全部的正整数,就不可能被放到一个列表之中去使用。但是,全部的正整数确实是应当可以被用作使用的,因为只需要通过前一个元素,就能够推断出后一个元素了。

因此,在这种情况下,我们有了一种新的东西,就是生成器,也就是generator。生成器无需一下子保存或读取出全部的内容,只需要在需要用到的时候,生成一个,就可以了。

生成器生成式

之前,我们提到了列表推导式,实际上,只要将列表推导式中的[]改为(),就可以创建一个生成器了。如果模仿列表生成式或者列表推导式的名字的话,也许我们应当称之为生成器生成式或者生成器推导式,不过这种说法似乎不是很常见。

注:关于列表推导式,有的时候我称呼其为列表推导式,有的时候我又称呼其为列表生成式,是因为这两种称呼非常通用,使用哪一种都是一样的,所以,就没有为了统一性,而选择只使用其中的一种说法。如果你觉得哪一种说法更好的话,可以自行使用其中的一种。

比如说,之前我们写过这样一个列表生成式,我们将其改为生成器生成式。

# 这是之前使用过的一个关于九九乘法表的列表推导式
li = ["%s * %s = %s" % (i, j, i * j) for i in range(1, 10) for j in range(1, 10) if i <= j]

# 将[]改为()以后,可以直接变成生成器
g_li = ("%s * %s = %s" % (i, j, i * j) for i in range(1, 10) for j in range(1, 10) if i <= j)

# 打印以后,我们可以看出,这是一个generator
print(g_li)

我们可以发现,直接打印一个生成器,是不可以的,因为它是在使用的过程中,才被生成的,因此,我们必须通过next()或者for循环的形式,去使用一个生成器。

# 每使用一次next(),就会新生成一个元素
print(next(g_li))
print(next(g_li))
print(next(g_li))
print(next(g_li))

# 使用for循环,可以通过遍历得到所有的元素
for i in g_li:
    print(i)

创建详细的生成器

虽然通过生成器生成式已经可以创建出生成器,但是,生成式的方式毕竟是一种比较简单的方式,面对一些复杂的需求的话,生成器难以应对。因此,我们可以通过函数定义的形式,得到一个生成器。

这里,我们需要使用一个关键字yield,当函数执行到yield时,会得到yield的内容,并且停止运行,当下一次调用的时候,会从上一次的yield开始继续运行,并执行到下一次yield再次暂停。

比如说,定义一个简单的生成器

# 通过函数,定义生成器
def g_num(x):
    for i in range(x):
        # 当执行到yield i的时候,会生成i,并且暂停
        # 当下一次调用的时候,会从这里继续运行,到下一个yield再次暂停
        yield i

注意,此时g_num不是一个生成器,g_num是一个函数。当这个函数被调用的时候,我们得到的是一个生成器。我们可以像这样使用。

# 生成器的使用
for i in g_num(100):
    print(i)

# 如果你不希望使用生成器,也可以通过list()
# 以此来将生成器直接转换为一个列表
a = list(g_num(10))

# 但是需要注意的是,不是所有的生成器都能够被转换为列表的
# 比如以下代码中,生成器是可以直接获取到的,但是如果你要将其转换为列表
# 可能就会失败或者使计算机陷入一些困境之中
x1 = g_num(1000000000000)
x2 = list(g_num(1000000000000))

总结

虽然通过next()或者for循环两种方式都可以使用生成器,但是一般来说,不会真的手动通过next()调用的。使用for循环来配合生成器使用要更多一些。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
生成器是一种特殊的迭代器,它可以在迭代过程动态生成值,而不需要一次生成所有值并存储在内存生成器使用 yield 语句来定义,当调用生成器函数时,它返回一个生成器对象。每次调用生成器的 __next__() 或者 next() 方法时,生成器会执行代码直到遇到 yield 关键字,然后返回 yield 后面的值,并暂停代码的执行状态。当再次调用 __next__() 或者 next() 方法时,生成器会从上次暂停的地方继续执行代码,直到再次遇到 yield 关键字或者函数结束。 通过使用生成器,我们可以按需生成迭代序列,而不必一次性生成所有数据。这在处理大量数据或者无限序列时非常有用。生成器还可以用于节约内存和提高性能。 以下是一个简单的生成器函数的例子: ```python def my_generator(): for i in range(5): yield i gen = my_generator() print(next(gen)) # 输出: 0 print(next(gen)) # 输出: 1 print(next(gen)) # 输出: 2 print(next(gen)) # 输出: 3 print(next(gen)) # 输出: 4 ``` 在这个例子,my_generator() 是一个生成器函数,它使用 for 循环和 yield 语句来生成从 0 到 4 的整数序列。通过调用 next() 方法,我们可以逐个获取生成器的值。每次调用 next() 方法时,生成器会从上次暂停的地方继续执行代码,直到遇到下一个 yield 语句。当没有可迭代的值时,生成器会引发 StopIteration 异常,表示迭代结束。 希望这样能够帮助你理解 Python 生成器!如果还有其他问题,请继续提问。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值