在Python中产生突破
根据这个问题的答案,C#中的yield break相当于在python中返回。 在正常情况下,“返回”确实停止了发电机。 但是,如果你的函数什么都不做,只能返回,你将得到一个None不是一个空的迭代器,它是通过在C#
def generate_nothing(): return for i in generate_nothing(): print i
你会得到一个TypeError:'NoneType'对象是不可迭代的。 但是如果我在返回之前添加一个永不退出的yield,这个函数返回我所期望的。
def generate_nothing(): if False: yield None return
如果工作,但似乎有线。 谁有更好的主意?
谢谢,
处理这个问题的一个好方法就是提高StopIteration ,当你的迭代器没有剩余的时候会产生StopIteration ,并调用next()
。 这也将优雅地摆脱循环执行循环内没有任何循环。
例如,给定一个元组(0, 1, 2, 3)
我想得到重叠对((0, 1), (1, 2), (2, 3))
。 我可以这样做:
def pairs(numbers): if len(numbers) < 2: raise StopIteration for i, number in enumerate(numbers[1:]): yield numbers[i], number
现在可以安全地处理1个或更less的列表。
def generate_nothing(): return yield
def generate_nothing(): return iter([])
有趣的是两个函数都有相同的字节码。 当字节码编译器findyield
关键字时,可能会有一个标志设置为generator
。
>>> def f(): ... return >>> def g(): ... if False: yield #in Python2 you can use 0 instead of False to achieve the same result >>> from dis import dis >>> dis(f) 2 0 LOAD_CONST 0 (None) 3 RETURN_VALUE >>> dis(g) 2 0 LOAD_CONST 0 (None) 3 RETURN_VALUE