使用Python 2.7,我试图编写代码以递归方式替换二维列表的元素。以下是该函数的代码片段:
import sys
sys.setrecursionlimit(10000)
def assimilate(population, x, y, influence):
"""Replace adjacent list elements recursively with -1 if cell is
lesser than the adjacent influenced cell.
Keyword arguments:
population -- 2D list of integers
x -- x-coordinate of influencing cell
y -- y-coordinate of influencing cell
influence -- value of influencing cell
Returns:
Modified population list.
"""
if population[y][x] <= influence:
population[y][x] = -1
if population[y][x] == -1:
# Check adjacent cells
if y - 1 > 0:
if population[y - 1][x] <= influence:
population = assimilate(population, y - 1, x, influence)
if x + 1 < len(population):
if population[y][x + 1] <= influence:
population = assimilate(population, y , x + 1, influence)
if y + 1 < len(population):
if population[y + 1][x] <= influence:
population = assimilate(population, y + 1, x, influence)
if x - 1 > 0:
if population[y][x - 1] <= influence:
population = assimilate(population, y, x - 1, influence)
return population
如果代码的值小于或等于-1
的值,则代码的目标是将相邻的列表元素(向上,向下,向左和向右,没有对角线)替换为influence
。它需要迭代,直到范围内所有可能的单元格都被转换。
这方面的一个例子是:
In: assimilate([[0, 1, 2], [8, 4, 5], [6, 7, 3]], 0, 0, 5)
Out: [[-1, -1, -1], [8, -1, -1], [6, 7, -1]]
Out (as a 2D list, visualized):
-1 -1 -1
8 -1 -1
6 7 -1
使用代码,输入5到influence
会导致输出错误,并且增加influence
的值会导致RuntimeError: maximum recursion depth exceeded
(通过添加import sys
和{ {1}}或sys.setrecursionlimit(10000)
。
三个问题:
递归不是强制性的,可以使用其他替代方案。我尝试使用Internal error: RangeError: Maximum call stack size exceeded
循环,但仍然输出错误。我尽量不要使用第三方软件包。
答案 0 :(得分:0)
这不是Python的问题,而是一个逻辑错误。
此处(以及其他类似地方)的逻辑存在问题,
如果人口[y] [x] <=影响:
population[y][x] = -1
让我们说,
人口[3] [2] = -1
。现在,在递归过程中,当程序来到
时种群[3] [1],它将看到它的相邻细胞&gt; (人口[3] [2])
小于影响值。如果影响是积极的,那将永远是真的。因此它将再次转向&gt;已经访问过一次的人口[3] [2]小区。因此递归调用将变为无限。
要检查此项,您可以更改以下行:
如果人口[y] [x]&lt; =影响和人口[y] [x]!= -1: 人口[y] [x] = -1
请知道此解决方案是否有效。您必须在if条件的每个位置更改此逻辑
编辑(带更正)
当它访问一个单元格并使其为-1时,它将不会再次进入该单元格并将停止递归。我实现了这个并且递归停止了。但这也是一个问题。如果有效为-1的单元格被高于影响的值包围,则永远不会访问它。
请考虑以下示例:
influence=5
[ 9, 9, 2 ]
[ 9, 9, 9 ]
[ 9, 9, 9 ]
在此示例中,如果仅检查-1,则永远不会访问2的单元格。因为,2被9包围,9将永远不会被-1替换。
为了解决这个问题,我们需要另一个能够跟踪访问的数组。该数组将初始化为0.如果已访问某个单元格,则其值将为1,并且永远不会重新访问访问的单元格。
检查以下代码。工作正常。
import sys
def assimilate(population, visited, y, x, influence):
visited[y][x] = 1
if population[y][x] <= influence:
population[y][x] = -1
# Check adjacent cells
if y - 1 >= 0:
if visited[y - 1][x] != 1:
population = assimilate(population, visited , y - 1, x, influence)
if x + 1 < len(population):
if visited[y][x + 1] != 1:
population = assimilate(population, visited , y , x + 1, influence)
if y + 1 < len(population):
if visited[y + 1][x] != 1:
population = assimilate(population, visited , y + 1, x, influence)
if x - 1 >= 0:
if visited[y][x - 1] != 1:
population = assimilate(population, visited , y, x - 1, influence)
return population
print assimilate( [[0, 1, 2], [8, 4, 5], [6, 7, 3]] , [[0,0,0],[0,0,0],[0,0,0]] , 0 , 0 , 5 )
<强>输出:强>
[[-1, -1, -1], [8, -1, -1], [6, 7, -1]]