Reputation: 43
I would like to move to the left of the main list ( or top seen as 2d list ) all the 0s. My solution is very naive and it's swapping only one value and when it reaches the end it's bringing last value at the begining ( which I don't need ). I've tried with collections deque but with no good output. I was thinking to a while loop as well but I couldn't find a solution.
x = [[0,2,1], [4,2,0], [0,0,0], [3,0,0]]
0 2 1 0 0 0
Input -->> 4 2 0 Output -->> 0 0 0 OR x = [ [0,0,0], [0,0,0], [4,2,0], [3,2,1] ]
0 0 0 4 2 0
3 0 0 3 2 1
for i in range(len(x)):
for index, j in enumerate(x[i]):
if j == 0:
x[i][index] = x[i-1][index]
x[i-1][index] = 0
Upvotes: 0
Views: 132
Reputation: 948
Let's start with the idea that you need to take a list or iterable and shuffle the zeros to the start -- this is needed for each column. Then you can do this is two transforms (each transposes the rows/columns) and a map via the shuffler:
x = zip(*map(shuffer, zip(*x)))
The shuffler can be implemented in any fashion, but I like generators; this specific implementation is two passes:
def shuffler(input):
for i in input:
if not i: yield 0
for i in input:
if i: yield i
Results seem correct to me:
>>> print zip(*map(shuffler, zip(*x)))
[(0, 0, 0), (0, 0, 0), (4, 2, 0), (3, 2, 1)]
Upvotes: 2
Reputation: 10799
Sorting columns based on being non-zero has the side effect of arranging the numbers in the desired order:
x = [[0, 2, 1], [4, 2, 0], [0, 0, 0], [3, 0, 0]]
print(list(map(list, zip(*(sorted(col, key=lambda n: n != 0) for col in zip(*x))))))
Output:
[[0, 0, 0], [0, 0, 0], [4, 2, 0], [3, 2, 1]]
>>>
Upvotes: 1