Пожалуйста, я немного новичок в Python и это было приятно, я мог бы прокомментировать, что python очень сексуален, пока мне не понадобилось переместить содержимое матрицы 4x4, которую я хочу использовать при создании игры 2048, демо-версия игры находится здесь, у меня есть эта функция
defcover_left(matrix): new=[[0,0,0,0],[0,0,0,0],[0,0,0,0],[0,0,0,0]] for i inrange(4): count=0 for j inrange(4): if mat[i][j]!=0: new[i][count]=mat[i][j] count+=1 return new
Вот что делает эта функция, если вы вызываете ее следующим образом
Пожалуйста, мне нужен кто-нибудь, кто поможет мне с numpy способом сделать это, который, я считаю, будет быстрее и потребует меньше кода (я использую алгоритм поиска в глубину) и, что более важно, с реализацией cover_up, cover_down и cover_left.
Вот векторизованный подход, вдохновленный this other post и обобщенный, чтобы охватить non-zeros все четыре направления -
defjustify(a, invalid_val=0, axis=1, side='left'): """ Justifies a 2D array
Parameters ---------- A : ndarray Input array to be justified axis : int Axis along which justification is to be made side : str Direction of justification. It could be 'left', 'right', 'up', 'down' It should be 'left' or 'right' for axis=1 and 'up' or 'down' for axis=0.
"""
if invalid_val is np.nan: mask = ~np.isnan(a) else: mask = a!=invalid_val justified_mask = np.sort(mask,axis=axis) if (side=='up') | (side=='left'): justified_mask = np.flip(justified_mask,axis=axis) out = np.full(a.shape, invalid_val) if axis==1: out[justified_mask] = a[mask] else: out.T[justified_mask.T] = a.T[mask.T] return out
defjustify_nd(a, invalid_val, axis, side): """ Justify ndarray for the valid elements (that are not invalid_val).
Parameters ---------- A : ndarray Input array to be justified invalid_val : scalar invalid value axis : int Axis along which justification is to be made side : str Direction of justification. Must be 'front' or 'end'. So, with 'front', valid elements are pushed to the front and with 'end' valid elements are pushed to the end along specified axis. """
if side=='front': justified_mask = np.flip(justified_mask,axis=axis)
out = np.full(a.shape, invalid_val) if (axis==-1) or (axis==a.ndim-1): out[justified_mask] = a[mask] else: pushax(out)[pushax(justified_mask)] = pushax(a)[pushax(mask)] return out
Примеры запусков -
Входной массив :
In [87]: a Out[87]: array([[[54, 57, 0, 77], [77, 0, 0, 31], [46, 0, 0, 98], [98, 22, 68, 75]],
defjustify(a, direction): mask = a>0 justified_mask = numpy.sort(mask,0) if direction == 'up'or direction =='down'else numpy.sort(mask, 1) if direction == 'up': justified_mask = justified_mask[::-1] if direction =='left': justified_mask = justified_mask[:,::-1] if direction =='right': justified_mask = justified_mask[::-1, :] out = numpy.zeros_like(a) out.T[justified_mask.T] = a.T[mask.T] return out