代码之家  ›  专栏  ›  技术社区  ›  Arseny

迭代器如何等价于itertools.count在Python中实现而不使用生成器函数?

  •  1
  • Arseny  · 技术社区  · 7 年前

    有了生成器函数,这就是 itertools.count documentation ):

    def count(start=0, step=1):
        # count(10) --> 10 11 12 13 14 ...
        # count(2.5, 0.5) -> 2.5 3.0 3.5 ...
        n = start
        while True:
            yield n
            n += step
    

    我试图找到一个类似的迭代器如何在没有生成器函数的情况下实现。

    class Count:
        def __init__(self, start=0, step=1):
            self.c = start
            self.step = step
    
        def __iter__(self):
            return self
    
        def __next__(self):
            n = self.c
            self.c += self.step
            return n
    

    1 回复  |  直到 7 年前
        1
  •  1
  •   Victor Ruiz    7 年前

    collections.abc.Iterator 用较少的代码实现计数

    from collections.abc import Iterator
    
    class count(Iterator):
        def __init__(self, start=0, step=1):
            self.c, self.step = start-step, step
    
        def __next__(self):
            self.c += self.step
            return self.c
    
        2
  •  1
  •   Laurent LAPORTE    7 年前

    unittest 这方面的框架。

    下面是一个示例,其中包含几个在循环中使用类并检查迭代器值的测试:

    import unittest
    import random
    
    
    class TestCount(unittest.TestCase):
        loops = 20
    
        def test_default(self):
            c = Count()
            for i in range(self.loops):
                self.assertEqual(i, next(c))
    
        def test_start(self):
            start = random.randint(-10, 10)
            c = Count(start=start)
            for i in range(start, start + self.loops):
                self.assertEqual(i, next(c))
    
        def test_step_pos(self):
            step = random.randint(1, 5)
            c = Count(step=step)
            for i in range(0, self.loops, step):
                self.assertEqual(i, next(c))
    
        def test_step_neg(self):
            step = random.randint(-5, -1)
            c = Count(step=step)
            for i in range(0, -self.loops, step):
                self.assertEqual(i, next(c))