Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/319.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 _iter__和next()函数_Python - Fatal编程技术网

Python _iter__和next()函数

Python _iter__和next()函数,python,Python,在Python中 我在类中定义了一个嵌套列表,如下所示: self.env = [[ None for i in range(columnCount)] for j in range(rowCount) ] 就本问题而言,假设此嵌套列表包含以下值: [None, None, None, None] [None, None, None, None] [None, None, 0, None] [None, None, None, None] 我需要能够利用iter和next()方

在Python中

我在类中定义了一个嵌套列表,如下所示:

self.env = [[ None for i in range(columnCount)] for j in range(rowCount) ]       
就本问题而言,假设此嵌套列表包含以下值:

[None, None, None, None]
[None, None, None, None]
[None, None, 0, None]
[None, None, None, None]
我需要能够利用iter和next()方法以列的主要顺序(row0、col0、row1、col0、row2、col0…)浏览此列表

其目的是将位于该网格位置的值发送给另一个函数进行处理

到目前为止,我将iter的功能定义为:

def __iter__(self):
    return iter(self.env)
def next(self):
    self.currentRow += 1
    self.currentColumn += 1

    if ( (self.currentRow < self.getRowCount()) and (self.currentColumn < self.getColumnCount()) ):
        return self.env[self.currentRow][self.currentColumn]
    else:
        raise StopIteration
然后我将下一个函数定义为:

def __iter__(self):
    return iter(self.env)
def next(self):
    self.currentRow += 1
    self.currentColumn += 1

    if ( (self.currentRow < self.getRowCount()) and (self.currentColumn < self.getColumnCount()) ):
        return self.env[self.currentRow][self.currentColumn]
    else:
        raise StopIteration
def next(self):
self.currentRow+=1
self.currentColumn+=1
如果((self.currentRow
我遇到的问题是,iter函数似乎是将每一行作为列表返回,但它没有调用下一个方法来进一步处理该列表

我的目标是分别打印每个网格位置的值。。。例如:

没有 没有一个 ... 没有一个 0 没有一个 ... 没有

有人能详细说明一下为了完成这项任务我缺少了什么吗

def __iter__(self):
    return (self.env[j][i] for i in range(columnCount)
                           for j in range(rowCount))

可能需要交换I和j

您的
\uuuuuuuuuuuuuuuuu
函数正在返回
iter(self.env)
,它返回self.env的迭代器。如果希望调用下一个方法,
\uu iter\uu
,则应返回
self
。但是在您的实现中还有其他问题,例如,迭代器只能工作一次

有更简单的方法来实现这一点。您可以编写一个生成器表达式/列表理解来实现这一点(参见@Eric的答案)。你也可以写一封信。例如:


你可能正在以一种非常复杂的方式接近

我会这样解决这个问题:

  • 再举一个例子——你的是对称的转置,所以你看不到做错的效果。让我们坐飞机吧

    x = [[1, 2, 3, 4], [5, 6, 7, 8]]
    
现在

  • 使用
    zip()
    或(对于大列表)更好的
    itertools.izip()
    进行转换,并删除一个级别:

    y = [j for i in itertools.izip(*x) for j in i]
    
    这里,
    izip()
    迭代所有给定列表,并将它们的第1、第2、。。。元素生成元组
    (1,5)、(2,6)
    等等
    i
    迭代这些元组,
    j
    迭代它们的项。所以
    y
    [1,5,2,6,3,7,4,8]

  • 现在,如果希望类实例以这种方式可移植,可以采用以下几种方法:

    • 您可以
      \uuuu iter\uuuu()
      作为生成器函数或返回迭代器,否则,例如。g

      def __iter__(self): return (j for i in itertools.izip(*self.env) for j in i)
      def __iter__(self):
          for i in itertools.izip(*self.env):
              for j in i: yield i
      def __iter__(self): return iter([j for i in itertools.izip(*self.env) for j in i])
      
      这样,您的对象是可编辑的,但不是迭代器

    • 您可以按照自己的意愿,让对象成为自己的迭代器,让
      \uu iter\uuu()
      返回
      self
      ,并实现
      next()
      。然而,我反对这一点,因为

      • 您需要自己跟踪索引
      • 一旦耗尽,您可以(也不应该)重新启动此迭代器,如下所示:

        […]一旦迭代器的next()方法引发StopIteration,它将在后续调用中继续这样做。不遵守此属性的实现将被视为已损坏。(这个约束是在Python2.3中添加的;在Python2.2中,各种迭代器根据这个规则被破坏。)

        因此,每次迭代都需要一个新对象

    • 您甚至可以使用
      \uuu getitem\uuu()
      做一些有趣的事情,就像Python的“最后一种ressort方法”一样,如果对象本身不提供迭代器,那么它是可移植的,如下所述:

Python调用
next()
\uuuu iter\uuuu()
返回的对象。