4

我昨天在做一个游戏,我必须遍历一个二维数组并找到任何标记为“d”的单元格的位置(其中单元格表示为“-”表示空白或“d”表示脏)。

我使用两个 for 循环来做到这一点:

def find_dirty_cells(board):

  dirty_cells = []
    for enum, row in enumerate(board):
      for enumrow, cell in enumerate(row):
        if cell == 'd':
          dirty_cells.append((enum, enumrow))

  return dirty_cells 

但后来我认为构建一个生成器对象并返回它可能会更好,所以我写了这个:

def find_dirty_cells(board):
  return ((enum, enumrow) for enumrow, cell in enumerate(row) for enum, row in enumerate(board) if cell == 'd')

但是第二个给了我不正确的数据作为响应(即,它没有找到“d”单元格)。我必须忽略一些简单的东西,使第二个不等于第一个,但我看不到它。我试图解决的真正问题是:有没有一种简单的方法可以让我的第一次尝试返回一个生成器?

4

3 回答 3

3

要将您的原始函数干净地转换为生成器,您需要的是yield语句,而不是return(或在您的特定情况下,而不是append)。我更喜欢这个版本而不是生成器表达式版本,因为原始版本更具可读性

def find_dirty_cells(board):
    for enum, row in enumerate(board):
        for enumrow, cell in enumerate(row):
            if cell == 'd':
                yield (enum, enumrow)
于 2013-07-01T15:20:16.743 回答
3

您需要for按照嵌套顺序列出循环:

def find_dirty_cells(board):
    return ((enum, enumrow) for enum, row in enumerate(board) for enumrow, cell in enumerate(row) if cell == 'd')

您已经交换了enumerate(board)andenumerate(row)循环,这仅row在会话或模块中仍有可用的全局变量时才有效。

在这种情况下,通过使用而不是使用生成器函数而不是生成器表达式可能更容易:yielddirty_cells.append()

def find_dirty_cells(board):
    for enum, row in enumerate(board):
        for enumrow, cell in enumerate(row):
            if cell == 'd':
                yield enum, enumrow

这将具有完全相同的效果,但可能更具可读性。

于 2013-07-01T15:19:51.910 回答
1

这是使用以下方法执行此操作的简单方法numpy.ndenumerate()

from numpy import ndenumerate
find_dirty_cells = lambda a: (i for i,v in ndenumerate(a) if v=='d')

这也适用于二维以上的数组。

于 2013-07-01T15:34:21.493 回答