有可能去除元素的循环

时间:2012-03-10 18:55:51

标签: python

我正在尝试编写一个类,它的工作方式与itertools模块的循环相同,但有一些额外的功能。我希望有可能从我正在迭代的列表中删除元素。

这是我的代码:

class myCycle(object):
    def __init__(self, list):
        self.list = list

    def __iter__(self):
        def iter(self):
            while True:
                if not self.list:
                    break
                for e in self.list:
                    yield e
        return iter(self)

    def remove(self, e):
        self.list.remove(e)

除了一个例外,它工作正常。我们来看看例子:

>>> for i in c:
...     print i
...     if i == 1:
...         c.remove(1)
...     if i == 3:
...         break
... 
1
3
>>> 

从列表中删除1后,索引移动,这可能是我输出中没有2的原因。

但我怎样才能让它发挥作用?或者可能有其他方法来获得此功能?

修改

在您发表意见后,我将尝试解释我正在尝试做什么。

我有一个包含玩家动作的字符串,看起来像这样:

actions = "sBcffcffcfrfccc"

来自扑克,动作f意味着弃牌,c跟注等等。对我们来说最有趣的是折叠。

我也有玩家名单:

players = ['Saxum', 'Erasmus', 'Anders', 'Ginger', 'Adam',
           'Crusoe', 'OgoPogo', 'Hari', 'Sanja', 'Hooke']

我想为每个玩家分配动作。所以我们正在通过行动和球员:

Saxum -> s
Erasmus -> B
Anders -> c
Ginger -> f

Ginger folded, we should remove this player. So how player list look like now:

    players = ['Saxum', 'Erasmus', 'Anders', 'Adam',
               'Crusoe', 'OgoPogo', 'Hari', 'Sanja', 'Hooke']

Adam -> f

Adam folded, we should remove this player. So how player list look like now:

    players = ['Saxum', 'Erasmus', 'Anders', 
               'Crusoe', 'OgoPogo', 'Hari', 'Sanja', 'Hooke']

Crusoe -> c
OgoPogo -> f

OgoPogo folded, we should remove this player. So how player list look like now:

    players = ['Saxum', 'Erasmus', 'Anders', 
               'Crusoe', 'Hari', 'Sanja', 'Hooke']

Hari -> f

Hari folded, we should remove this player. So how player list look like now:

    players = ['Saxum', 'Erasmus', 'Anders', 
               'Crusoe', 'Sanja', 'Hooke']

Sanja -> c
Hooke -> f

Hooke folded, we should remove this player. So how player list look like now:

    players = ['Saxum', 'Erasmus', 'Anders', 
               'Crusoe', 'Sanja']

Hooke was last on the list, so we start from beginning.

Saxum -> r
Erasmus -> f

Erasmus folded, we should remove this player. So how player list look like now:

    players = ['Saxum', 'Anders', 
           'Crusoe', 'Sanja']

Anders -> c
Crusoe -> c
Sanja -> c

这就是我开始实施myCycle的原因。但也许有更好的方法来做到这一点?

3 个答案:

答案 0 :(得分:3)

请勿删除列表中已删除的项目 - 请将其替换为None

class MyCycle(object):
    def __init__(self, lst):
        self.list = lst

    def __iter__(self):
        while True:
            items_left = False
            for x in self.list:
                if x is not None:
                    items_left = True
                    yield x
            if not items_left:
                return

    def remove(self, e):
        self.list[self.list.index(e)] = None

答案 1 :(得分:2)

您可以使用while循环:

index = 0

while index < len(my_list):
    if got_to_remove(my_list[index]):
        del l[index]
    else:
        index += 1

现在,正如您在问题的评论中指出的那样,您可能会找到更优雅的问题解决方案。

答案 2 :(得分:1)

实际上,这可以通过手工制作迭代器而不是使用生成器函数来实现。

class myCycle(object):
    def __init__(self, list):
        self.list = list
        self.i = 0

    def __next__(self):
        try:
            return self.list[self.i]
        except IndexError:
            raise StopIteration, "list is empty"
        finally:
            self.i = self.i + 1
            if self.i >= len(self.list):
                self.i = 0
    next = __next__

    def __iter__(self):
        return self

    def remove(self, e):
        i = self.list.index(e)
        del self.list[i]
        if self.i >= i:
            self.i = self.i - 1
        if self.i >= len(self.list):
            self.i = 0