gpt4 book ai didi

python - 在以下情况下使用生成器函数有什么好处?

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

我的任务目标是无限期地生成列表元素。所以我这样做了:

SERVERS = ['APP1', 'APP2', 'APP3']
#SERVERS = ['APP1', 'APP2', 'APP3', 'APP4', 'APP5', 'APP6']
length = len(SERVERS)

def get_server():
current_server = SERVERS.pop(0)
SERVERS.append(current_server)
return current_server

if __name__ == '__main__':
for i in range(9):
print get_server()

解决方案是这样的:

SERVERS = ['APP1', 'APP2', 'APP3']
#SERVERS = ['APP1', 'APP2', 'APP3', 'APP4', 'APP5', 'APP6']

def get_server():
def f():
while True:
i = SERVERS.pop(0)
SERVERS.append(i)
yield i
return next(f())

if __name__ == '__main__':
for i in range(9):
print get_server()

尽管两种情况下的输出相同:

codewingx@CodeLair:~/repo/python$ python load_balancer.py
APP1
APP2
APP3
APP1
APP2
APP3
APP1
APP2
APP3

那么生成器函数有什么好处呢?

最佳答案

使用itertools.cycle()

生成器不会在这里添加任何有用的东西。我会尽量避免 pop(0) 因为它每次都会触发整个服务器列表的重建。

我会推荐 itertools.cycle() :

from __future__ import print_function

from itertools import cycle

SERVERS = ['APP1', 'APP2', 'APP3']

servers = cycle(SERVERS)

for i in range(9):
print(next(servers))

输出:

APP1
APP2
APP3
APP1
APP2
APP3
APP1
APP2
APP3

我们包装在一个函数中以匹配您的用法:

def make_get_server():
servers = cycle(SERVERS)
def get_server():
return next(servers)
return get_server

get_server = make_get_server()

for i in range(9):
print(get_server())

输出:

APP1
APP2
APP3
APP1
APP2
APP3
APP1
APP2
APP3

编写自己的生成器函数

为了说明生成器的意义,利用其存储 stet 能力的变体可能更有用:

def gen():
index = 0
end = len(SERVERS)
while True:
yield SERVERS[index]
index += 1
if index >= end:
index = 0

虽然这很好地说明了您有使用 index 的状态,但可以通过以下方式更轻松地实现相同的目的:

def gen():
while True:
for server in SERVERS:
yield server

g = gen()

def get_server():
return next(g)

这避免了修改 SERVERS 列表。结果是一样的:

for i in range(9):
print(get_server())

输出:

APP1
APP2
APP3
APP1
APP2
APP3
APP1
APP2
APP3

发电机的工作原理

一个简单的生成器函数:

>>> def gen():
... print('start')
... yield 1
... print('after 1')
... yield 2
... print('after 2')
...

创建实例:

>>> g = gen()

使用next获取yield返回的下一个值:

>>> next(g)
start
1

继续:

>>> next(g)
after 1
2

现在它已经用完了:

>>> next(g)
after 2

StopIteration next(g)

您可能会想到在生成器函数中移动的光标。每次调用 next() 时,它都会移动到下一个 yield。因此,将 yield 放在 while True 循环中会生成一个无限生成器。只要您不对其调用 close(),它就会为您提供一个带有 yield 的新值。此外,您在生成器中有状态。这意味着您可以执行一些操作,例如在对 next() 的调用之间递增计数器。

关于python - 在以下情况下使用生成器函数有什么好处?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35241382/

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