5

我需要构建一个生成器,并且我正在寻找一种方法将这个 for 循环缩短为一行。我尝试枚举,但没有奏效。

counter=0
for element in string:
    if function(element):
        counter+=1
        yield counter
    else:
        yield counter
4

4 回答 4

6
counter=0
for element in string:
    counter+=bool(function(element))
    yield counter

(是的,将布尔值添加到 ints 就像Truewas1Falsewas一样工作0)。

bool()仅当可以function()具有除TrueFalse1和之外的返回值时,才需要调用0

于 2013-04-30T23:23:49.053 回答
4

function首先,您可以将字符串转换为返回值的迭代器:

truths = (function(x) for x in string)

然后您可以将它们映射到 0 和 1:

onesandzeroes = (1 if function(x) else 0 for x in string)

然后累积它们:

running = itertools.accumulate(1 if function(x) else 0 for x in string)

如文档所述,accumulate是在 Python 3.2 中添加的。如果您使用的是 2.x,则可以从文档中复制并粘贴“等效于”配方。(如果您使用的是 3.0-3.1,您也可以这样做,但实际上,在这种情况下,只需升级即可。)

于 2013-04-30T23:25:24.700 回答
4

如果您使用的是 Python 3,则可以执行以下操作:

from itertools import accumulate

yield from accumulate(1 if function(x) else 0 for x in string)

虽然我会使用Simeon Visser 的回答。虽然这可能很短,但目前还不清楚代码的作用。

于 2013-04-30T23:20:26.290 回答
3

您可以将其缩短为:

counter=0
for element in string:
    if function(element):
        counter+=1
    yield counter
于 2013-04-30T23:20:55.997 回答