单个方法中的顺序 yield 语句
Sequential yield statements in a single method
我知道连续写几个 return
语句从来没有用过,因为第二个语句将无法访问,例如:
def return_something():
return 2
return "Kolia" # unreachable
但是连续写几个yield
语句有什么用呢?
def yield_something():
yield 3
yield 4
print(next(yield_something()))
print(next(yield_something()))
>>> 3
>>> 3
在我看来,我曾在某处看到顺序 yield
的使用,而我的 IDE 并未突出显示它。谁能告诉我顺序 yield
的使用?
以下说明了您示例中顺序产量的使用:
def yield_something():
yield 3
yield 4
a = yield_something()
print(next(a))
print(next(a))
输出
3
4
在您的示例中,每次调用 yield_something()
都会创建一个新生成器。使用 a = yield_something()
创建生成器,然后每次需要 yield
.
时使用 next()
您总是在使用 yield_something()
时创建一个新的生成器。您应该创建一个生成器:a = yield_something()
,然后在 那个 生成器上调用 next(a)
:
def yield_something():
yield 3
yield 4
a = yield_something() # Generator
print(next(a)) # 3
print(next(a)) # 4
但通常您会在生成器中定义一个循环来生成 yields
:
def yield_something():
for i in (3,4):
yield i
或者如果可以计算它们,那么生成器真的很强大,因为它不需要在内存中保存值列表:
def yield_something():
i = 3
while i < 5:
yield i
i += 1
顺序 yield 可以替代或替换为常量元组中的 yield 值。
for i in (1,7,3,20):
yield i
# versus
yield 1; yield 7; yield 3; yield 20
或者,您的代码中可能有多个 yield
,做不同的事情。我不会将这些 顺序收益 视为更大函数的两个部分:
def unzip_dict(d):
for k in d.keys():
yield k
for v in d.values():
yield v
是的,甚至还有真实的单词示例。如果您看一下 this prime sieve implementation here on Whosebug,您会发现它使用的是顺序收益率。虽然这是真的,但它只是在这里用作优化。
以下代码来自tzot的回答:
import itertools as it
def erat3( ):
D = { 9: 3, 25: 5 }
yield 2
yield 3
yield 5
MASK= 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0,
MODULOS= frozenset( (1, 7, 11, 13, 17, 19, 23, 29) )
for q in it.compress(
it.islice(it.count(7), 0, None, 2),
it.cycle(MASK)):
p = D.pop(q, None)
if p is None:
D[q*q] = q
yield q
else:
x = q + 2*p
while x in D or (x%30) not in MODULOS:
x += 2*p
D[x] = p
我知道连续写几个 return
语句从来没有用过,因为第二个语句将无法访问,例如:
def return_something():
return 2
return "Kolia" # unreachable
但是连续写几个yield
语句有什么用呢?
def yield_something():
yield 3
yield 4
print(next(yield_something()))
print(next(yield_something()))
>>> 3
>>> 3
在我看来,我曾在某处看到顺序 yield
的使用,而我的 IDE 并未突出显示它。谁能告诉我顺序 yield
的使用?
以下说明了您示例中顺序产量的使用:
def yield_something():
yield 3
yield 4
a = yield_something()
print(next(a))
print(next(a))
输出
3
4
在您的示例中,每次调用 yield_something()
都会创建一个新生成器。使用 a = yield_something()
创建生成器,然后每次需要 yield
.
next()
您总是在使用 yield_something()
时创建一个新的生成器。您应该创建一个生成器:a = yield_something()
,然后在 那个 生成器上调用 next(a)
:
def yield_something():
yield 3
yield 4
a = yield_something() # Generator
print(next(a)) # 3
print(next(a)) # 4
但通常您会在生成器中定义一个循环来生成 yields
:
def yield_something():
for i in (3,4):
yield i
或者如果可以计算它们,那么生成器真的很强大,因为它不需要在内存中保存值列表:
def yield_something():
i = 3
while i < 5:
yield i
i += 1
顺序 yield 可以替代或替换为常量元组中的 yield 值。
for i in (1,7,3,20):
yield i
# versus
yield 1; yield 7; yield 3; yield 20
或者,您的代码中可能有多个 yield
,做不同的事情。我不会将这些 顺序收益 视为更大函数的两个部分:
def unzip_dict(d):
for k in d.keys():
yield k
for v in d.values():
yield v
是的,甚至还有真实的单词示例。如果您看一下 this prime sieve implementation here on Whosebug,您会发现它使用的是顺序收益率。虽然这是真的,但它只是在这里用作优化。
以下代码来自tzot的回答:
import itertools as it
def erat3( ):
D = { 9: 3, 25: 5 }
yield 2
yield 3
yield 5
MASK= 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 0, 0,
MODULOS= frozenset( (1, 7, 11, 13, 17, 19, 23, 29) )
for q in it.compress(
it.islice(it.count(7), 0, None, 2),
it.cycle(MASK)):
p = D.pop(q, None)
if p is None:
D[q*q] = q
yield q
else:
x = q + 2*p
while x in D or (x%30) not in MODULOS:
x += 2*p
D[x] = p