如何在列表列表中移动项目?
How to move an Item inside a list of lists?
我有以下列表列表,表示存储在 space
中的矩阵:
[' ', '1', '1', ' ']
[' ', '1', ' ', ' ']
[' ', '1', ' ', ' ']
[' ', ' ', ' ', ' ']
数字 1s 代表倒置的 L(如伽玛,“Γ”)。我怎样才能让这个“物体”像块一样左右移动?我用“asdw”键移动它
我尝试这样做是为了做出正确的方向运动(顺便说一句,它没有做出正确的运动),但我认为这不是最好的方法,也不认为我真的可以将其升级为其他运动:
x = input("Movement: ")
if x == 'd':
for i in range(4):
for j in range(4):
if space[i][j] == '1':
try:
if space[i][j+1] == ' ':
space[i][j] = ' '
space[i][j+1] = '1'
if space[i][j+1] == '1' and space[i][j+2] == ' ':
space[i][j] = ' '
space[i][j+2] = '1'
except IndexError:
pass
还有其他方法可以尝试吗?或者更正我正在使用的那个?提前致谢
实现此目的的一种方法是将其视为矩阵并应用矩阵变换。这不会阻止人物离开屏幕,但会移动它并且比你现在做的更有效。
为简单起见,我会将您的矩阵转换为 1 和 0,因为使用起来更简单:
import numpy as np
data = np.array([
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 0],
])
要对整个矩阵应用右平移和左平移,您需要分别对 right
和 left
数组执行矩阵乘法:
right = np.array([
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 0, 0, 0],
])
left = np.array([
[0, 0, 0, 0],
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
])
例如,
print(data, '\n')
d = np.matmul(data, right)
print(d, '\n')
d = np.matmul(d, right)
print(d)
Out:
[[0 1 1 0]
[0 1 0 0]
[0 1 0 0]
[0 0 0 0]]
[[0 0 1 1]
[0 0 1 0]
[0 0 1 0]
[0 0 0 0]]
[[0 0 0 1]
[0 0 0 1]
[0 0 0 1]
[0 0 0 0]]
很明显,这里的问题是,一旦碰到边缘,它就不会停止,数值就会丢失。
列表的列表对于表示矩阵来说很笨重。相反,您可以使用实际的 matrix-like 类型,即可用于平移形状的 NumPy ndarray. NumPy includes a roll()
函数,因此您只需要提供方向即可。
首先,为了更好的可读性,我将使用 0 和 1。
import numpy as np
space = np.array([
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 0],
])
然后我们就可以正确滚动了:
>>> np.roll(space, 1, 1)
[[0 0 1 1]
[0 0 1 0]
[0 0 1 0]
[0 0 0 0]]
要执行其他方向,您只需要提供正确的值,您可以将其包装在这样的函数中:
def move_shape_in_array(array, direction):
directions = {
"up": (-1, 0),
"left": (-1, 1),
"down": (1, 0),
"right": (1, 1),
}
shift, axis = directions[direction]
return np.roll(array, shift=shift, axis=axis)
>>> move_shape_in_array(space, "right")
[[0 0 1 1]
[0 0 1 0]
[0 0 1 0]
[0 0 0 0]]
但这并不能防止形状超出边缘。相反,它环绕着:
>>> move_shape_in_array(space, "up")
[[0 1 0 0]
[0 1 0 0]
[0 0 0 0]
[0 1 1 0]]
要真正防范,在移动之前检查边上是否有1:
edge_idx = 0 if shift == -1 else -1
edge = array[edge_idx] if axis == 0 else array[:, edge_idx]
if edge.any():
return array
(将其插入上述函数的 shift, axis =
和 return
行之间。)
我有以下列表列表,表示存储在 space
中的矩阵:
[' ', '1', '1', ' ']
[' ', '1', ' ', ' ']
[' ', '1', ' ', ' ']
[' ', ' ', ' ', ' ']
数字 1s 代表倒置的 L(如伽玛,“Γ”)。我怎样才能让这个“物体”像块一样左右移动?我用“asdw”键移动它
我尝试这样做是为了做出正确的方向运动(顺便说一句,它没有做出正确的运动),但我认为这不是最好的方法,也不认为我真的可以将其升级为其他运动:
x = input("Movement: ")
if x == 'd':
for i in range(4):
for j in range(4):
if space[i][j] == '1':
try:
if space[i][j+1] == ' ':
space[i][j] = ' '
space[i][j+1] = '1'
if space[i][j+1] == '1' and space[i][j+2] == ' ':
space[i][j] = ' '
space[i][j+2] = '1'
except IndexError:
pass
还有其他方法可以尝试吗?或者更正我正在使用的那个?提前致谢
实现此目的的一种方法是将其视为矩阵并应用矩阵变换。这不会阻止人物离开屏幕,但会移动它并且比你现在做的更有效。
为简单起见,我会将您的矩阵转换为 1 和 0,因为使用起来更简单:
import numpy as np
data = np.array([
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 0],
])
要对整个矩阵应用右平移和左平移,您需要分别对 right
和 left
数组执行矩阵乘法:
right = np.array([
[0, 1, 0, 0],
[0, 0, 1, 0],
[0, 0, 0, 1],
[0, 0, 0, 0],
])
left = np.array([
[0, 0, 0, 0],
[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 1, 0],
])
例如,
print(data, '\n')
d = np.matmul(data, right)
print(d, '\n')
d = np.matmul(d, right)
print(d)
Out:
[[0 1 1 0]
[0 1 0 0]
[0 1 0 0]
[0 0 0 0]]
[[0 0 1 1]
[0 0 1 0]
[0 0 1 0]
[0 0 0 0]]
[[0 0 0 1]
[0 0 0 1]
[0 0 0 1]
[0 0 0 0]]
很明显,这里的问题是,一旦碰到边缘,它就不会停止,数值就会丢失。
列表的列表对于表示矩阵来说很笨重。相反,您可以使用实际的 matrix-like 类型,即可用于平移形状的 NumPy ndarray. NumPy includes a roll()
函数,因此您只需要提供方向即可。
首先,为了更好的可读性,我将使用 0 和 1。
import numpy as np
space = np.array([
[0, 1, 1, 0],
[0, 1, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 0],
])
然后我们就可以正确滚动了:
>>> np.roll(space, 1, 1)
[[0 0 1 1]
[0 0 1 0]
[0 0 1 0]
[0 0 0 0]]
要执行其他方向,您只需要提供正确的值,您可以将其包装在这样的函数中:
def move_shape_in_array(array, direction):
directions = {
"up": (-1, 0),
"left": (-1, 1),
"down": (1, 0),
"right": (1, 1),
}
shift, axis = directions[direction]
return np.roll(array, shift=shift, axis=axis)
>>> move_shape_in_array(space, "right")
[[0 0 1 1]
[0 0 1 0]
[0 0 1 0]
[0 0 0 0]]
但这并不能防止形状超出边缘。相反,它环绕着:
>>> move_shape_in_array(space, "up")
[[0 1 0 0]
[0 1 0 0]
[0 0 0 0]
[0 1 1 0]]
要真正防范,在移动之前检查边上是否有1:
edge_idx = 0 if shift == -1 else -1
edge = array[edge_idx] if axis == 0 else array[:, edge_idx]
if edge.any():
return array
(将其插入上述函数的 shift, axis =
和 return
行之间。)