我以不寻常的顺序遍历二维列表(我的矩阵表示):从左上角的元素开始逆时针绕着外部。
我需要不止一次这样做,但每次我这样做,我都想做一些与我遇到的价值不同的事情。第一次,我想记下这些值,以便我可以修改它们。 (我无法在适当的位置修改它们。)第二次,我想遍历矩阵的外部并按照我的方式修改矩阵的值,也许从某个生成器获取我的新值。
有没有办法可以将这个遍历抽象为一个函数并仍然实现我的目标?我在想这个遍历边缘函数可以使用函数和矩阵,并将函数应用于矩阵边缘上的每个元素。但是,这个问题是双重的。如果我这样做,我不认为我可以修改作为参数给出的矩阵,并且我不能逐一产生这些值,因为yield isn' ta函数。 / p>
编辑:我想逆时针旋转矩阵(不是90度),其中一个旋转移动,例如,左上角元素向下移动一个点。要做到这一点,我要旋转一个"等级"一次(或壳)矩阵。因此,如果我旋转最外层,我想遍历它一次以建立一个我可以向左移动的列表,然后我想再次遍历最外层以为它分配我计算的那些新值。 / p>
答案 0 :(得分:1)
只需创建4个循环,每个循环一个数组,用于计算该方面更改的索引值。例如,x索引始终为0的第一个边可以将y从0变为n-2(从左上角到左下角的shy);重复另一方。
答案 1 :(得分:1)
我认为您可以采取两种方法来解决问题。
第一个选项是创建一个函数,该函数将可迭代的索引返回到矩阵中。然后你用for
循环在矩阵上写下你的各种传递:
for i, j in matrix_border_index_gen(len(matrix), len(matrix[0])): # pass in dimensions
# do something with matrix[i][j]
另一种选择是编写一个更像map
的函数,它将给定函数依次应用于矩阵的每个适当值。如果您有时需要用新的值替换当前值,我建议您一直这样做(当您不想替换值时,您可以让您的函数返回之前的值) ):
def func(value):
# do stuff with value from matrix
return new_value # new_value can be the same value, if you don't want to change it
matrix_border_map(func, matrix) # replace each value on border of matrix with func(value)
答案 2 :(得分:1)
我在这里添加了几行python 3代码。它具有镜像功能和螺旋迭代器(不确定,如果这是你的意思)。没有doc字符串(抱歉)。虽然它是可读的。更改python 2的打印语句。
编辑:修复了一个错误
class Matrix():
def __init__(self, rows=5, cols=5):
self.cells = [[None for c in range(cols)] for r in range(rows)]
def transpose(self):
self.cells = list(map(list, zip(*self.cells)))
def mirror(self):
for row in self.cells:
row.reverse()
def invert(self):
self.cells.reverse()
def rotate(self, clockwise=True):
self.transpose()
self.mirror() if clockwise else self.invert()
def iter_spiral(self, grid=None):
grid = grid or self.cells
next_grid = []
for cell in reversed(grid[0]):
yield cell
for row in grid[1:-1]:
yield row[0]
next_grid.append(row[1:-1])
if len(grid) > 1:
for cell in grid[-1]:
yield cell
for row in reversed(grid[1:-1]):
yield row[-1]
if next_grid:
for cell in self.iter_spiral(grid=next_grid):
yield cell
def show(self):
for row in self.cells:
print(row)
def test_matrix():
m = Matrix()
m.cells = [[1,2,3,4],
[5,6,7,8],
[9,10,11,12],
[13,14,15,16]]
print("We expect the spiral to be:", "4, 3, 2, 1, 5, 9, 13, 14, 15, 16, 12, 8, 7, 6, 10, 11", sep='\n')
print("What the iterator yields:")
for cell in m.iter_spiral():
print(cell, end=', ')
print("\nThe matrix looks like this:")
m.show()
print("Now this is how it looks rotated 90 deg clockwise")
m.rotate()
m.show()
print("Now we'll rotate it back")
m.rotate(clockwise=False)
m.show()
print("Now we'll transpose it")
m.transpose()
m.show()
print("Inverting the above")
m.invert()
m.show()
print("Mirroring the above")
m.mirror()
m.show()
if __name__ == '__main__':
test_matrix()
这是输出:
We expect the spiral to be:
4, 3, 2, 1, 5, 9, 13, 14, 15, 16, 12, 8, 7, 6, 10, 11
What the iterator yields:
4, 3, 2, 1, 5, 9, 13, 14, 15, 16, 12, 8, 7, 6, 10, 11,
The matrix looks like this:
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
[13, 14, 15, 16]
Now this is how it looks rotated 90 deg clockwise
[13, 9, 5, 1]
[14, 10, 6, 2]
[15, 11, 7, 3]
[16, 12, 8, 4]
Now we'll rotate it back
[1, 2, 3, 4]
[5, 6, 7, 8]
[9, 10, 11, 12]
[13, 14, 15, 16]
Now we'll transpose it
[1, 5, 9, 13]
[2, 6, 10, 14]
[3, 7, 11, 15]
[4, 8, 12, 16]
Inverting the above
[4, 8, 12, 16]
[3, 7, 11, 15]
[2, 6, 10, 14]
[1, 5, 9, 13]
Mirroring the above
[16, 12, 8, 4]
[15, 11, 7, 3]
[14, 10, 6, 2]
[13, 9, 5, 1]
答案 3 :(得分:0)
我会选择generator functions。它们可用于创建我们可以迭代的迭代器。生成器函数的示例 -
def genfunc():
i = 0
while i < 10:
yield i
i = i + 1
>>> for x in genfunc():
... print(x)
...
0
1
2
3
4
5
6
7
8
9
调用生成器函数时,它返回一个生成器对象 -
>>> genfunc()
<generator object genfunc at 0x00553AD0>
此时不会开始检查该功能。当你开始遍历生成器对象,调用它的第一个元素时,它开始遍历函数,直到它到达第一个yield语句,然后它返回值(在上面的例子中,它返回值{{1 })。并且它还保存了该点的函数状态(即它保存了在生成值时执行的时间点,本地命名空间中变量的值等等)。
然后当它试图获得下一个值时,再次执行从上次停止的位置开始,直到它再次产生另一个值。这种情况还在继续。