在列表推导式或生成器表达式中使用while

21

我可以在列表推导式/生成器表达式中使用 iffor 关键字,如下:

list(i for i in range(100) if i*i < 30)

我知道这并不是最有效率的方法,但请容忍我,因为条件可能更加复杂,这只是一个示例。然而,这仍然需要进行数百次迭代,而且只在前6次迭代中产生一个值。是否有一种方法可以告诉生成器表达式何时停止,例如:

list(i for i in range(100) while i*i < 30)

然而,在生成器表达式中无法理解while。因此,我的问题是,如何编写带有停止条件的生成器表达式,以便即使它不生成新值,也不会继续计算。


1
只是一个提醒:您可以直接使用 [i for i in range(100)] 生成列表。 - Joril
1
有趣的是,在提出这个问题时,PEP3142 正在进行中。给出的用例几乎与此相同。Guido在2013年5月将其删除。 - John La Rooy
2个回答

27

由于takewhile()dropwhile()的语法不是很清晰,因此以下是实际的示例回答您的问题:

>>> [i for i in itertools.takewhile(lambda x: x*x<30, range(10))]
[0, 1, 2, 3, 4, 5]
>>> [i for i in itertools.dropwhile(lambda x: x*x<30, range(10))]
[6, 7, 8, 9] 

了解到itertools的作者 曾经质疑 是否应该弃用这些函数。


如果这些函数被弃用了,那么应该采取什么措施? - highBandWidth
只需查看Python文档中的itertools.takewhileitertools.dropwhile。每个函数都有对应的Python等效实现。 - dawg
7
这里难道不是使用 list(itertools.takewhile(lambda x: x*x<30, range(10))) 比列表推导式更简单吗? - wim
@wim 我把链接指向了相同的消息,不同的主机。谢谢。 - dawg

14

在IT技术中,itertools库中的各种函数(比如takewhile())可以提供帮助。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接