我将iter与两个参数一起使用,并且想知道是否存在可以接受更复杂标记的标记?

例如,在下面的代码中

# returns digits 1 to 10 upon subsequently calling .create(),
# then returns 'END' each time afterwards
class MyClass:
    def __init__(self):
        self.counter = 0
    def create(self):
        self.counter += 1
        if self.counter > 10:
            return 'END'
        else:
            return self.counter

c = MyClass()
for i in iter(c.create, 'END'):
    print(i)


迭代在获得'END'后结束。我想在总共得到两个'END'后结束它(不一定一个接一个-上面的代码将在前十个调用之后仅生成'END',但可以想象一下它们是与其他值交错)。

本质上,我正在寻找一种使用更复杂的哨兵的方法。有这样的概念吗?

我知道我可以求助于previous question中提到的明显但丑陋的代码,但@HappyLeapSecond答案是如此优雅,我希望保持这种精神(我通过itertools进行了尝试,但是似乎没有可用的方法可以做到)工作)

最佳答案

您可以将itertools.takewhile与有状态的predicate一起使用。例如:

>>> from itertools import takewhile
>>> def create_predicate(func, max_count):
    """Return False only when func evaluates True for the max_count time."""
    def predicate(elem):
        if func(elem):
            predicate.count += 1
        if predicate.count == max_count:
            return False
        return True
    predicate.count = 0
    return predicate

>>> list(takewhile(create_predicate(lambda elem: elem % 3 == 0, 3), range(1, 20)))
[1, 2, 3, 4, 5, 6, 7, 8]


在上面的示例中,create_predicate(lambda elem: elem % 3 == 0, 3)创建一个复杂的谓词函数,该函数将停止三个整数的第三个整数的迭代。就你而言


  我想在总共得到两个'END'之后结束它


您可以使用create_predicate(lambda elem: elem == 'END', 2)

关于python - 是否有接受复杂哨兵的迭代器?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/31407061/

10-13 08:24