Python 遍历多维数组的元素并查找邻居-无numpy或导入

Python 遍历多维数组的元素并查找邻居-无numpy或导入,python,arrays,list,recursion,multidimensional-array,Python,Arrays,List,Recursion,Multidimensional Array,在python中,如何在不使用numpy或任何导入(仅使用递归)的情况下迭代多维数组的元素并查找其邻居?例如,minesweeper_board=[[0,b']、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]]]标记炸弹,我想更新每个零周围的炸弹数量(就像在扫雷游戏中一样) 我建议为每个行/列对建立一个指向相邻坐标的链接字典。在程序的许多部分中,当您需要计算位置周围的值时,这可以用作间接寻址: minesweep

在python中,如何在不使用numpy或任何导入(仅使用递归)的情况下迭代多维数组的元素并查找其邻居?例如,
minesweeper_board=[[0,b']、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]、[0,0]]]
标记炸弹,我想更新每个零周围的炸弹数量(就像在扫雷游戏中一样)

我建议为每个行/列对建立一个指向相邻坐标的链接字典。在程序的许多部分中,当您需要计算位置周围的值时,这可以用作间接寻址:

minesweeper_board = [ [ [0, 'b'], [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], ['b', 0] ],
                      [ [0, 0],   [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], [0, 0]   ]
                    ]

rows      = 4
cols      = 3
offsets   = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]

def inBoard(r,c): return r in range(rows) and c in range(cols)

def getNeighbours(r,c): return [(r+v,c+h) for v,h in offsets if inBoard(r+v,c+h)] 

links = { (r,c):getNeighbours(r,c) for r in range(rows) for c in range(cols) }
使用链接字典:

for (r,c),neighbours in links.items():
    bombCount = sum('b' in minesweeper_board[nr][nc] for nr,nc in neighbours) 
    if bombCount:
        print(f"there are {bombCount} bombs near {(r,c)}")
输出:

there are 2 bombs near (0, 1)
there are 1 bombs near (0, 2)
there are 1 bombs near (1, 0)
there are 2 bombs near (1, 1)
there are 1 bombs near (2, 1)
there are 1 bombs near (2, 2)
minesweeper_board = [ [ [0, 'b'], [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], ['b', 0] ],
                      [ [0, 0],   [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], [0, 0]   ]
                    ]

countBombs(minesweeper_board)
print(minesweeper_board)

[
   [ [1, 'b'], [2, 2], [1, 1]   ],
   [  [1, 1],  [2, 2], ['b', 1] ],
   [  [0, 0],  [1, 1], [1, 1]   ],
   [  [0, 0],  [0, 0], [0, 0]   ]
]


getCell(minesweeper_board,1,2,0) # 'b'
getCell(minesweeper_board,1,1,1) # 2
[编辑]多维电路板的通用化

我最初误解了这个问题,但可以通过创建递归n维访问函数来推广上述解决方案。Python的列表或列表结构不适合通过多个维度进行索引:
board[1][2][3]
与numpy的
board[1,2,3]
相比有点笨拙,但我们可以使用函数(或创建一个全新的类,这将需要更多的工作)来弥补这一点:

输出:

there are 2 bombs near (0, 1)
there are 1 bombs near (0, 2)
there are 1 bombs near (1, 0)
there are 2 bombs near (1, 1)
there are 1 bombs near (2, 1)
there are 1 bombs near (2, 2)
minesweeper_board = [ [ [0, 'b'], [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], ['b', 0] ],
                      [ [0, 0],   [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], [0, 0]   ]
                    ]

countBombs(minesweeper_board)
print(minesweeper_board)

[
   [ [1, 'b'], [2, 2], [1, 1]   ],
   [  [1, 1],  [2, 2], ['b', 1] ],
   [  [0, 0],  [1, 1], [1, 1]   ],
   [  [0, 0],  [0, 0], [0, 0]   ]
]


getCell(minesweeper_board,1,2,0) # 'b'
getCell(minesweeper_board,1,1,1) # 2

我建议为每一行/列对建立一个指向相邻坐标的链接字典。在程序的许多部分中,当您需要计算位置周围的值时,这可以用作间接寻址:

minesweeper_board = [ [ [0, 'b'], [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], ['b', 0] ],
                      [ [0, 0],   [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], [0, 0]   ]
                    ]

rows      = 4
cols      = 3
offsets   = [(-1,-1),(-1,0),(-1,1),(0,-1),(0,1),(1,-1),(1,0),(1,1)]

def inBoard(r,c): return r in range(rows) and c in range(cols)

def getNeighbours(r,c): return [(r+v,c+h) for v,h in offsets if inBoard(r+v,c+h)] 

links = { (r,c):getNeighbours(r,c) for r in range(rows) for c in range(cols) }
使用链接字典:

for (r,c),neighbours in links.items():
    bombCount = sum('b' in minesweeper_board[nr][nc] for nr,nc in neighbours) 
    if bombCount:
        print(f"there are {bombCount} bombs near {(r,c)}")
输出:

there are 2 bombs near (0, 1)
there are 1 bombs near (0, 2)
there are 1 bombs near (1, 0)
there are 2 bombs near (1, 1)
there are 1 bombs near (2, 1)
there are 1 bombs near (2, 2)
minesweeper_board = [ [ [0, 'b'], [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], ['b', 0] ],
                      [ [0, 0],   [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], [0, 0]   ]
                    ]

countBombs(minesweeper_board)
print(minesweeper_board)

[
   [ [1, 'b'], [2, 2], [1, 1]   ],
   [  [1, 1],  [2, 2], ['b', 1] ],
   [  [0, 0],  [1, 1], [1, 1]   ],
   [  [0, 0],  [0, 0], [0, 0]   ]
]


getCell(minesweeper_board,1,2,0) # 'b'
getCell(minesweeper_board,1,1,1) # 2
[编辑]多维电路板的通用化

我最初误解了这个问题,但可以通过创建递归n维访问函数来推广上述解决方案。Python的列表或列表结构不适合通过多个维度进行索引:
board[1][2][3]
与numpy的
board[1,2,3]
相比有点笨拙,但我们可以使用函数(或创建一个全新的类,这将需要更多的工作)来弥补这一点:

输出:

there are 2 bombs near (0, 1)
there are 1 bombs near (0, 2)
there are 1 bombs near (1, 0)
there are 2 bombs near (1, 1)
there are 1 bombs near (2, 1)
there are 1 bombs near (2, 2)
minesweeper_board = [ [ [0, 'b'], [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], ['b', 0] ],
                      [ [0, 0],   [0, 0], [0, 0]   ],
                      [ [0, 0],   [0, 0], [0, 0]   ]
                    ]

countBombs(minesweeper_board)
print(minesweeper_board)

[
   [ [1, 'b'], [2, 2], [1, 1]   ],
   [  [1, 1],  [2, 2], ['b', 1] ],
   [  [0, 0],  [1, 1], [1, 1]   ],
   [  [0, 0],  [0, 0], [0, 0]   ]
]


getCell(minesweeper_board,1,2,0) # 'b'
getCell(minesweeper_board,1,1,1) # 2

我遇到了同样的问题,我不得不为numpy.exp()函数做一个替代,因为它可以遍历n维列表。但我在网上找不到任何解决方案,这是我能找到的唯一stackoverflow线程,但没有找到解决方案。所以我自己做了一个函数,使用递归遍历n维列表。 iterate(list)函数接受一个n维列表,并使用递归对其进行迭代

import math

def iterate(list1):
    for x in range(len(list1)):
        if isinstance(list1[x], list):
            iterate(list1[x])
        else:
            list1[x]=math.exp(list1[x]) # Manipulate the elements as you require

list2 = [[[2, 1], [3, 5], [6, 7]], [[8, 9], [6, 7], [12, 5]], [[3, 7], [2, 2], [3, 4]], [[5, 6], [7, 8], [9, 8]]]
iterate(list2)
print(list2)
此特定方法将把n维列表1中的每个元素x更改为e^x

输出:

[[[7.38905609893065, 2.718281828459045], [20.085536923187668, 148.4131591025766], [403.4287934927351, 1096.6331584284585]], [[2980.9579870417283, 8103.083927575384], [403.4287934927351, 1096.6331584284585], [162754.79141900392, 148.4131591025766]], [[20.085536923187668, 1096.6331584284585], [7.38905609893065, 7.38905609893065], [20.085536923187668, 54.598150033144236]], [[148.4131591025766, 403.4287934927351], [1096.6331584284585, 2980.9579870417283], [8103.083927575384, 2980.9579870417283]]]

我遇到了同样的问题,我不得不为numpy.exp()函数做一个替代,因为它可以遍历n维列表。但我在网上找不到任何解决方案,这是我能找到的唯一stackoverflow线程,但没有找到解决方案。所以我自己做了一个函数,使用递归遍历n维列表。 iterate(list)函数接受一个n维列表,并使用递归对其进行迭代

import math

def iterate(list1):
    for x in range(len(list1)):
        if isinstance(list1[x], list):
            iterate(list1[x])
        else:
            list1[x]=math.exp(list1[x]) # Manipulate the elements as you require

list2 = [[[2, 1], [3, 5], [6, 7]], [[8, 9], [6, 7], [12, 5]], [[3, 7], [2, 2], [3, 4]], [[5, 6], [7, 8], [9, 8]]]
iterate(list2)
print(list2)
此特定方法将把n维列表1中的每个元素x更改为e^x

输出:

[[[7.38905609893065, 2.718281828459045], [20.085536923187668, 148.4131591025766], [403.4287934927351, 1096.6331584284585]], [[2980.9579870417283, 8103.083927575384], [403.4287934927351, 1096.6331584284585], [162754.79141900392, 148.4131591025766]], [[20.085536923187668, 1096.6331584284585], [7.38905609893065, 7.38905609893065], [20.085536923187668, 54.598150033144236]], [[148.4131591025766, 403.4287934927351], [1096.6331584284585, 2980.9579870417283], [8103.083927575384, 2980.9579870417283]]]

所以在我开始回答之前,我很难想象你的数据结构-你能提供一些关于它是如何构造的更多信息吗?对于
扫雷船板
维度=(4,3,2)
->3d board-我的问题是如何递归地遍历具有维度元组(长度为n)的n维数组的元素并找到邻居。为什么要递归?@James我明白了,我想尽可能自信地回答你的问题——你提供的例子与你的评论不太相符,我只是在想最好的搜索方法。您提供了4个数组的列表,每个数组有3个2x1元组。我只是很难想象这是如何融入3d空间的。@Błotosmętek,递归地,因为我希望能够在n维网格中找到细胞的邻居-如果它是一个固定的3d网格,我可以通过在每个维度上获得+/-1索引的细胞索引轻松找到邻居。@matt murray,一个维度为的列表(4,3,2)是4层3x2的正方形。所以在我开始回答之前,我很难想象你的数据结构-你能提供一些关于它是如何构造的更多信息吗?对于
扫雷板
维度=(4,3,2)
->3d board-我的问题是如何使用一个维度元组(长度为n)递归遍历n维数组的元素然后找到邻居。为什么是递归的?@James我明白了,我想尽可能自信地回答你的问题-你提供的例子不太适合你的评论,我只是在想最好的搜索方法。你提供了一个4个数组的列表,每个数组有3个2x1元组。我只是很难想象如何搜索这适用于3d空间。@Błotosmętek,递归地,因为我希望能够在n维网格中找到单元格的邻居-如果它是一个设置的3d网格,我可以通过在每个维度上获得+/-1索引的单元格索引轻松找到邻居。@matt murray,维度为(4,3,2)的列表是4层3x2的正方形。好主意!但是,我已经有了一些类似的代码-我只需要可以为变量n维列表执行此操作的代码。我希望能够使用任意维元组构建网格,比如(4,3,2)用于3D,甚至(5,3,6,2,8,5)用于6D(我已经有了代码)函数应该通过递归获取每个位置的相邻单元来获取每个单元的邻居。我喜欢这种技巧,在函数调用中将
rest
解包到
pos
rest
。但是我对
[*getnextries(board,*coord)]
有疑问-它比
列表(getnextries(board,*coord))好吗
以任何方式?