修改Itertools.cycle()

1 投票
2 回答
1800 浏览
提问于 2025-04-18 11:14

我现在在使用 itertools.cycle() 这个对象,我想知道有没有办法在创建后修改这个循环。下面的代码:

my_cycle = itertools.cycle([1,2,3])
print my_cycle.next()
my_cycle.delete()    #function doesn't exist
print my_cycle.next()

会输出:

1
3

有没有办法通过 itertools 来实现这个?或者用其他的对象?还是说我需要自己实现一个对象来做到这一点。

2 个回答

2

如果你想跳过一个值,可以直接调用一次 next

如果你想永久性地从循环中移除一个值,可以创建一个生成器。

def skip_matching(gen, value):
    for v in gen:
        if v == value:
            continue
        yield v

然后你可以像这样包装一个循环:

>>> a = skip_matching(itertools.cycle([1,2,3]), 2)
>>> a.next()
1
>>> a.next()
3
>>> a.next()
1

如果你想按位置移除下一个值(而不移除其他匹配的值),你需要知道循环的长度 n。然后你可以跳过一个值,收集 n-1 个值来创建一个新的循环。

c.next()
c = itertools.cycle(c.next() for i in range(n-1))
4

Itertools这个库没有提供这样的选项。不过你可以用一个叫做deque的工具来自己实现。

from collections import deque

class ModifiableCycle(object):
    def __init__(self, items=()):
        self.deque = deque(items)
    def __iter__(self):
        return self
    def __next__(self):
        if not self.deque:
            raise StopIteration
        item = self.deque.popleft()
        self.deque.append(item)
        return item
    next = __next__
    def delete_next(self):
        self.deque.popleft()
    def delete_prev(self):
        # Deletes the item just returned.
        # I suspect this will be more useful than the other method.
        self.deque.pop()

撰写回答