<p>这可能有点笨拙,但列表理解总是一个选择。你知道吗</p>
<pre><code>def countInGrid(grid, key):
return [sum([v[i:i+2].count(key) for v in grid[j:j+2]])
for j in range(0, len(grid), 2) for i in range(0, len(grid[0]), 2)]
</code></pre>
<p>通过这个,它使用的2x2网格是<code>[v[i:i+2] for v in grid[j:j+2]</code>。如果你对整个列表做了很多次,这并不是一个超高效的操作,但是写起来很快。你知道吗</p>
<p>要对键进行计数,它首先使用<code>.count(key)</code>对每一行进行计数,然后使用<code>sum()</code>对2x2网格中的每两行进行相加。你知道吗</p>
<p>最后一行是如何选择要查看的2x2网格。它指定从何处开始,从何处结束。如果不想先遍历列,然后遍历行,<code>i</code>和<code>j</code>的顺序很重要。你知道吗</p>
<p>列表理解基本上将以下所有小组件打包成一个更紧凑的语法。你知道吗</p>
<pre><code>def count_row(v, key):
return v.count(key)
def count_grid(grid, key):
return sum(count_row(v, key) for v in grid)
def get_nxn(grid, i, j, n=2):
return [v[i:i+n] for v in grid[j:j+n]]
def iter_block_row(grid, j):
for i in range(0, len(grid[0]), 2):
yield get_nxn(grid, i, j)
def iter_grid(grid):
for j in range(0, len(grid), 2):
# In Python 3.3+, use
# yield from iter_block_row(grid, j)
for g in iter_block_row(grid, j):
yield g
def count_in_grid(grid, key):
return [count_grid(g, key) for g in iter_grid(grid)]
</code></pre>
<p>把大问题看成是由小部分组成,有助于用任何经验使它们易于处理。你不需要任何额外的语法糖和语言技巧就能以一种干净的方式实现同样的目标,这也是很有帮助的。你知道吗</p>
<p><strong>注意<code>get_nxn()</code>中的片效率非常低。这是分解问题的一种方法(我认为从概念上考虑是最简单的方法),但不是最有效的方法。你知道吗</p>
<p><strong>更新</strong>我对<code>get_nxn()</code>效率低下的看法是错误的。看起来Python中的列表片不会复制数据,甚至可以追溯到python2.7+。相对于<code>grid</code>的大小,<code>get_nxn()</code>操作以恒定时间运行,并且在该时间是一个快速的恒定时间。你知道吗</p>