Gabriel
Gabriel

Reputation: 43

Swapping elements with the same index between 2 or more lists

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

Answers (2)

F1Rumors
F1Rumors

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

Paul M.
Paul M.

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

Related Questions