Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/variables/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python迭代器类索引在for循环运行的第二次出现溢出_Python_Iterator - Fatal编程技术网

Python迭代器类索引在for循环运行的第二次出现溢出

Python迭代器类索引在for循环运行的第二次出现溢出,python,iterator,Python,Iterator,我定义了一个包含对象列表集合的类,并定义了\uuuuu iter\uuuuu和\uuuu next\uuuuu方法,使其成为可循环的。这里的集合是一个Deck类,它包含卡对象的列表 代码: 随机导入 班级卡: @静力学方法 def get_等级(): 回报率(“A”、“K”、“Q”、“J”、“10”、“9”、“8”、“7”、“6”、“5”、“4”、“3”、“2”)#A最高,2最低 @静力学方法 def get_suites(): 报税表(“H”、“D”、“S”、“C”) 定义初始(自我、套件、等

我定义了一个包含对象列表集合的类,并定义了
\uuuuu iter\uuuuu
\uuuu next\uuuuu
方法,使其成为可循环的。这里的集合是一个
Deck
类,它包含
对象的列表

代码:
随机导入
班级卡:
@静力学方法
def get_等级():
回报率(“A”、“K”、“Q”、“J”、“10”、“9”、“8”、“7”、“6”、“5”、“4”、“3”、“2”)#A最高,2最低
@静力学方法
def get_suites():
报税表(“H”、“D”、“S”、“C”)
定义初始(自我、套件、等级):
如果套件不在卡中。获取套件()
引发异常(“无效套件”)
如果等级不在卡中。获取等级()
引发异常(“无效秩”)
self.suite=suite
self.rank=等级
def\uuuu lt\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
self_-rank=卡。获取_-ranks()索引(self.rank)
card2_-rank=Card.get_-ranks()索引(card2.rank)
返回自我排名>卡片2排名
定义(自我,卡片2):
self_-rank=卡。获取_-ranks()索引(self.rank)
card2_-rank=Card.get_-ranks()索引(card2.rank)
返回自我排名>=card2排名
def\uuu gt\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
self_-rank=卡。获取_-ranks()索引(self.rank)
card2_-rank=Card.get_-ranks()索引(card2.rank)
返回自我等级
在运行时,我遇到以下错误:
我们有8H和KH
50张卡片:9H、8C、AC、7C、6H、2S、2D、5C、10H、5H、JS、5S、KD、JH、JC、QS、2H、3H、3S、3D、4C、4H、AD、KS、JD、QH、10D、6S、5D、8D、3C、6C、7D、AS、7H、AH、9S、10C、QC、QD、7S、2C、KC、8S、4D、4S、6D、10S、10S、9C
51张卡片:QS
[7D,5C,10H,QS]
52张卡片:10C
[KC,3S,9H,10C]
我们有2C和QD
回溯(最近一次呼叫最后一次):
文件“playing_cards.py”,第106行,在
印刷品(甲板)
文件“playing_cards.py”,第88行,在__
对于自助卡:
文件“playing_cards.py”,第73行,在下一个__
项目=自目录[自索引]
索引器:列表索引超出范围
在for循环的第二次运行中,当我将card对象推回到列表中时,情况似乎不一样。如何在保持弹出、推送功能的同时解决此问题

编辑:
self.index
在第一次调用
print()
后为50。当卡片被添加回列表时,索引保持在50,而牌组长度现在是51张。因此,在第二次(和第三次)打印调用中,将打印最后一张卡片,而不是整个卡片组。随后出现错误


我想我在这里读错了。我的问题是我应该在
StopIteration
位重置索引吗。这是正确的方法吗,还是索引应该自行重置?

不确定您是如何到达的,但您超出了列表的长度。建议您比较列表的
=
长度,如:

def __next__(self):
    if self.index >= len(self.contents):
        raise StopIteration
    .....

我不知道你是怎么做到的,但你已经超出了你的名单。建议您比较列表的
=
长度,如:

def __next__(self):
    if self.index >= len(self.contents):
        raise StopIteration
    .....

进行以下更改

def __iter__(self):
    self.index = 0
    return self
因此每次调用
\uu iter\uu
,都会重置
索引。
出现此错误的原因是,一旦您迭代了
deck
,在迭代结束时,
self.index==len(self.contents)

下次迭代时,
self.index
应重置为
0


我做了上述更改,它对我有效。

做以下更改

def __iter__(self):
    self.index = 0
    return self
因此每次调用
\uu iter\uu
,都会重置
索引。
出现此错误的原因是,一旦您迭代了
deck
,在迭代结束时,
self.index==len(self.contents)

下次迭代时,
self.index
应重置为
0


我做了上述更改,它对我有效。

注意:如果您试图通过实现自己的迭代器来学习迭代器的工作原理,那么上面的建议适用。如果您只想使您的
数据组
更易于使用,您可以在
数据组
中执行此操作:

def __iter__(self):
    return self.contents  # lists are already iterable
更妙的是,如果您希望您的数据组的行为类似于列表(迭代、索引、切片、删除),您可以扩展
list

学习迭代器的工作原理:

这里的问题是将集合与迭代器合并。集合应包含一组项。您的
Deck
是一个集合。集合是可编辑的,这意味着我可以对集合中的x执行
。当我们对集合中的x执行
时,Python实际上对iter(集合)
中的x执行
,这将集合转换为迭代器

您希望迭代器和集合分开。如果集合是它自己的迭代器,那么一次只能有一个迭代器(它本身)。还要注意迭代器只能使用一次。通过在
\uu iter\uuu
中执行
self.index=0
,可以使迭代器(
Deck
)可重用

考虑以下几点:

nums = [1, 2, 3]

for i in nums:
    for j in nums:
        print(i, j)
我们预计这种情况还会出现:

1 1
1 2
1 3
2 1
2 2
2 3
3 1
3 2
3 3
请注意,每次内部循环迭代整个集合时。如果
nums
是它自己的迭代器,那么我们会遇到一些问题:

# Here internally nums sets the current index as 0
for i in nums:
   # Here internally nums sets the current index as 0 again
   for j in nums:
       print(i, j)

   # Once this inner loop finishes the current index is 4.
   # But that is also the index for the outer loop, so the
   # outer loop ends too
意外输出:

1 1
1 2
1 3
解决方案是
Deck_
class Deck:
    # ... snip ...

    def __iter__(self):
        return DeckIterator(self.contents)

class DeckIterator:
    def __init__(self, cards):
        self.index = 0
        self.cards = cards

    def __iter__(self):
        return self

    def __next__(self):
        if self.index >= len(self.cards):
            # We've gotten the end of the deck/list
            raise StopIteration

        item = self.cards[self.index]
        self.index += 1
        return item
class BadList(list):
    def __iter__(self):
        self._current_index = 0
        return self

    def __next__(self):
        print(f'current index is {self._current_index}', end='')

        if self._current_index >= len(self):
            print(' which is the end, so ending iteration')
            raise StopIteration

        item = self[self._current_index]
        print(f' so returning value {item}')
        self._current_index += 1
        return item

# Using letters instead of numbers so difference between indices
# and items is more clear
letters = BadList('abc')

for i in letters:
    for j in letters:
        print(i, j)
current index is 0 so returning value "a"
current index is 0 so returning value "a"
a a
current index is 1 so returning value "b"
a b
current index is 2 so returning value "c"
a c
current index is 3 which is the end, so ending iteration
current index is 3 which is the end, so ending iteration
if self.index >= len(self.contents):
class Deck:
    def __init__(self):
        self.contents = [Card(suite, rank)
                         for suite in Card.get_suites()
                         for rank in Card.get_ranks()]
        random.shuffle(self.contents)
        # no index here

    def __iter__(self):
        return DeckIterator(self)

    # other methods, but no __next__

class DeckIterator:
    def __init__(self, deck):
        self.deck = deck
        self.index = 0

    def __iter__(self):
        return self

    def __next__(self):
        if self.index > len(self.deck):
            raise StopIteration

        value = self.deck.contents[self.index]
        self.index += 1
        return value