MTG MTG - 6 months ago 65
Python Question

Python - Move Elements to the End of a 2-Dimensional Array?

Given this 2D Array - [[0, 0, -1], [1, 0, -2], [2, 0, -3], [3, 0, 0]]

How can I code something in Python that moves everything to the end? (If the end is empty).

So I get something like this - [[0, 0, 0], [1, 0, -1], [2, 0, -2], [3, 0, -3]]

I tried something like this:

count = 0
while count < row: # row is 4 in this case.
if my_array[row-1][2] == 0:
tp = my_array[count][2]
my_array[count][2] = 0
my_array[count+1][2] = tp
else:
break
count += 1
return my_array


But this is what I get instead:
[[0, 0, 0], [0, 0, 0], [0, 0, 0], [0, 0, -1]]

Update:

Thanks @furas, I spent hours trying to figure this out
How can I also handle a gap in the middle? So if I get something like this:

data = [[0, 0, -1], [0, 0, 0], [0, 0, -3], [0, 0, -4]]

expected = [[0, 0, 0], [0, 0, -1], [0, 0, -3], [0, 0, -4]]

rows = len(data)

if data[-1][-1] == 0:
count = rows-1
while count > 0:
data[count][-1] = data[count-1][-1]
count -= 1
data[0][-1] = 0

print(data)
print(expected)
print(data == expected) # False


Thanks

UPDATE Nov.29 -

I have certain scenarios like these that don't work? Can you help?

DATA: [[0, 0, 0, 0], [1, 2, 1, 0], [2, 1, 2, 0], [0, 0, 0, 0]]

EXPECT: [[0, 0, 0, 0], [0, 0, 0, 0], [1, 2, 1, 0], [2, 1, 2, 0]]

Or if it's negative:

DATA: [[0, 0, 0, 0], [-101, -101, -101, 0], [2, 3, 2, 0], [3, 2, 3, 0]]

EXPECT: [[0, 0, 0, 0], [0, 0, 0, 0], [2, 3, 2, 0], [3, 2, 3, 0]]

Thanks A lot!!

Answer Source

I got something like this

def move(data):  
    row = len(data)-1
    prev = row-1

    while row > 0 and prev >= 0:
        if data[row][-1] == 0:
            while prev >= 0 and data[prev][-1] == 0:
                prev -= 1
            data[row][-1] = data[prev][-1]
            data[prev][-1] = 0
        row -= 1
        prev -= 1        

    return data

# --- test ---

examples = [
  {
    'data': [[0, 0, -1], [0, 0, 0], [0, 0, -3], [0, 0, -4]],
    'expected': [[0, 0, 0], [0, 0, -1], [0, 0, -3], [0, 0, -4]],
   },
  {
    'data': [[0, 0, -1], [1, 0, -2], [2, 0, -3], [3, 0, 0]],
    'expected': [[0, 0, 0], [1, 0, -1], [2, 0, -2], [3, 0, -3]],
   },
]

for ex in examples:
    print(ex['data'])
    result = move(ex['data'])
    print(ex['expected'])
    print(result == ex['expected']) # True

I use rows = len(data) and [-1] so it can have any size.

External while check if place row is empty and start internal while which is looking for not-empty elements prev before row. After that it move non-empty element from prev to row and put zero in prev. And it starts again with next row place.

It looks more complicated then other solutions.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download