Reputation: 47
I'm building a basic mapping robot where all the data is stored on a 2D python array. However I am unable to find any way to move entire rows or columns over and then insert a blank row/column in. For example:
['#','0','0']
['0','1','0']
['#','0','0']
if moved to the right to look like :
['0','#','0']
['0','0','1']
['0','#','0']
or
['#','0','#']
['0','1','0']
['0','0','0']
if moved down to look like :
['0','0','0']
['#','0','#']
['0','1','0']
I have already figured out how to expand the array whenever something is detected outside of the pre-defined array however I am unable to move rows and columns like demonstrated above.
Any help would be greatly appreciated. Thanks :)
Upvotes: 3
Views: 7893
Reputation: 22544
The numpy solutions work great, but here is a solution in pure Python, with no imports. Note that most of this code just prints the results--each roll uses only one line of code. I also added shiftedup
, where the matrix is rotated up then the last row is replaced with all zeros (though it is done more efficiently than that).
myarray = [
[1, 2, 3],
[4, 5, 6],
[7, 8, 9],
]
print('\nOriginal:')
for row in myarray:
print(row)
rolledup = myarray[1:] + myarray[:1]
print('\nRolled up:')
for row in rolledup:
print(row)
rolleddown = myarray[-1:] + myarray[:-1]
print('\nRolled down:')
for row in rolleddown:
print(row)
rolledleft = [row[1:] + row[:1] for row in myarray]
print('\nRolled left:')
for row in rolledleft:
print(row)
rolledright = [row[-1:] + row[:-1] for row in myarray]
print('\nRolled right:')
for row in rolledright:
print(row)
shiftedup= myarray[1:] + [[0] * len(myarray[0])]
print('\nShifted up:')
for row in shiftedup:
print(row)
The printout from that is:
Original:
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
Rolled up:
[4, 5, 6]
[7, 8, 9]
[1, 2, 3]
Rolled down:
[7, 8, 9]
[1, 2, 3]
[4, 5, 6]
Rolled left:
[2, 3, 1]
[5, 6, 4]
[8, 9, 7]
Rolled right:
[3, 1, 2]
[6, 4, 5]
[9, 7, 8]
Shifted up:
[4, 5, 6]
[7, 8, 9]
[0, 0, 0]
Upvotes: 2
Reputation: 917
This can be easily done by "roll" function from numpy
example in your case:
import numpy as np
a = np.array([['#','0','0'], ['0','1','0'], ['#','0','0']])
output will be:
array([['#', '0', '0'],
['0', '1', '0'],
['#', '0', '0']], dtype='<U1')
for 1st usecase:
np.roll(a, 1, 1)
output will be
array([['0', '#', '0'],
['0', '0', '1'],
['0', '#', '0']], dtype='<U1')
for second case yo can simply take transpose:
a.T
and output will be
array([['#', '0', '#'],
['0', '1', '0'],
['0', '0', '0']], dtype='<U1')
Third case be done by applying numpy roll operation on transpose matrix
np.roll(a.T, 1, 0)
output
array([['0', '0', '0'],
['#', '0', '#'],
['0', '1', '0']], dtype='<U1')
Upvotes: 0
Reputation: 3610
You can create a class to handle this movements like this:
class Board(object):
def __init__(self, rows):
self.rows = rows
self.print_status()
def print_status(self):
for row in self.rows:
print(row)
def right(self):
new_rows = []
for row in self.rows:
row = row[-1:] + row[:len(row)-1]
new_rows.append(row)
self.rows = new_rows
self.print_status()
def left(self):
new_rows = []
for row in self.rows:
row = row[1:] + row[:1]
new_rows.append(row)
self.rows = new_rows
self.print_status()
def up(self):
new_rows = []
for row in self.rows[1:]:
new_rows.append(row)
new_rows.append(self.rows[0])
self.rows = new_rows
self.print_status()
def down(self):
new_rows = []
new_rows.append(self.rows[-1])
for row in self.rows[:-1]:
new_rows.append(row)
self.rows = new_rows
self.print_status()
Example:
>>> a = Board([[1,2,3],[4,5,6],[7,8,9]])
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
>>> a.down()
[7, 8, 9]
[1, 2, 3]
[4, 5, 6]
>>> a.up()
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
>>> a.right()
[3, 1, 2]
[6, 4, 5]
[9, 7, 8]
Upvotes: 1
Reputation: 7510
Have you looked at numpy and numpy.roll for this?
import numpy as np
a = np.array([['#','0','0'],
['0','1','0'],
['#','0','0']])
then you can shift right:
a = np.roll(a,1)
a[:,0] = 0
shift left:
a = np.roll(a,-1)
a[:,-1] = 0
shift up:
a = np.roll(a,-1,axis = 0)
a[-1,:] = 0
shift down:
a = np.roll(a,1,axis = 0)
a[0,:] = 0
Upvotes: 3