【问题标题】:Modify Itertools.cycle()修改 Itertools.cycle()
【发布时间】:2014-08-17 18:09:48
【问题描述】:

我目前正在使用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 来实现吗?或者也许是另一个对象?或者我需要实现我自己的对象来做到这一点。

【问题讨论】:

  • 你想达到什么目的?

标签: python cycle itertools


【解决方案1】:

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()

【讨论】:

  • 我不知道这些!凉爽的!谢谢。
【解决方案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))

【讨论】:

  • skip_matching 在一个循环中出现多次或删除循环的所有内容时不会做正确的事情。
  • @user2357112,是的,我提到了前者。对于后者,有正确的做法吗?
  • 提高StopIteration 对我来说似乎是正确的事情。
  • @user2357112,是的,也许,但如果给你一个未知长度的循环,这是不可能的。你必须再次知道长度。因此,像您一样使用自定义类可能是更明智的选择。
猜你喜欢
  • 2011-07-11
  • 2016-08-11
  • 2019-02-12
  • 2020-12-05
  • 2016-07-10
  • 1970-01-01
  • 2018-08-11
  • 1970-01-01
  • 2017-06-17
相关资源
最近更新 更多