【发布时间】:2020-09-06 01:53:23
【问题描述】:
创建了以下生成器函数:
def hailstone(n):
yield n
while n > 1:
n = n // 2 if n % 2 == 0 else n * 3 + 1
yield n
作为冰雹序列的生成器函数对我有用,现在我尝试从生成器表达式(单行)生成相同的输出。
我正努力朝着这个方向发展:
hailstone = (num // 2 if num % 2 == 0 else num * 3 + 1 for i in range("something here"))
其中 num 作为第一个数字传递。 我注意到使用范围可能不是正确的路径,但我需要一个停止条件。
我想弄清楚的主要事情:
- 如何将 next() 输出传递回生成器以生成序列?
- 如何提供停止条件?
对执行此任务有帮助吗?
【问题讨论】:
-
没有很好的方法来转换这样的 while 循环,它依赖于主体内的值作为停止生成器表达式的条件。就用这个吧。
-
要使用生成器表达式,您需要生成一个无限序列,然后使用
take_while函数或其他东西。当您提前知道要进行多少次迭代(或至少可能的最大迭代次数)时,通常会使用生成器表达式。对于列表推导/生成器表达式来说,迭代直到一个条件是一个糟糕的用例,因为这些构造是为了迭代现有的可迭代对象。 -
是的,理解结构是围绕在可迭代对象上表达映射/过滤转换而设计的。它们并不意味着将所有东西都变成一条线。 Python 是一种足够动态的语言,可以让你做各种恶作剧,所以我想有一些方法可以完成你想要的,但你绝对不应该那样做。跨度>
-
hailstone = lambda num: (num if i == 0 else (num:=num // 2) if num % 2 == 0 else (num:=num * 3 + 1) for i, _ in enumerate(iter(lambda: num, 1)))太丑了,别用了。 -
@AndrejKese 巧妙地使用了 iter 的两个参数形式,但天哪,这太恶心了
iter(lambda: num, 1)。 ...我想我更喜欢takewhile,我真的不喜欢那个功能
标签: python generator list-comprehension