deep
deep

Reputation: 15

How to get rid of nested for loop

mazeHow do i replace the nested for loop without affecting the functionality of the code:

def addCoordinate(self, x, y, blockType):
    if self.x1 < x :
        self.x1 = x
    if self.y1 < y:
        self.y1 = y
    if self.x1 >= len(self.mazeboard) or self.y1 >= len(self.mazeboard):
        modified_board = [[1 for a in range(self.x1 + 1)] for b in range(self.y1 + 1)]
        for a in range(len(self.mazeboard)):
            for b in range(len(self.mazeboard[a])):
                modified_board[a][b] = self.mazeboard[a][b]
        self.mazeboard = modified_board
    self.mazeboard[x][y] = blockType

Upvotes: 0

Views: 268

Answers (2)

dawg
dawg

Reputation: 103864

If you work with a matrix in Python, you may want to consider using Numpy

You example becomes trivial with numpy. First, import numpy:

>>> import numpy as np

Create the 5x5 matrix:

>>> a=np.ones(shape=(5,5))
>>> a
array([[ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.],
       [ 1.,  1.,  1.,  1.,  1.]])

Expand that matrix with 5 more columns and 5 more rows:

>>> a=np.pad(a,((0,5),(0,5)),mode='constant', constant_values=0)
>>> a
array([[ 1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 1.,  1.,  1.,  1.,  1.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
       [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])

Instead of nested Python loops, you will have C code executing matrix function many times faster and more efficiently.

Upvotes: 0

Jean-Fran&#231;ois Fabre
Jean-Fran&#231;ois Fabre

Reputation: 140188

Yes, the nested loops & the range(len(self.mazeboard)) are highly unpythonic here, most of all when you just want to extend a matrix like

0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0
0 0 0 0 0

to

0 0 0 0 0 1 1 1
0 0 0 0 0 1 1 1
0 0 0 0 0 1 1 1
0 0 0 0 0 1 1 1
0 0 0 0 0 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1

you could work in-place, completing the existing rows with ones, and adding rows of ones until you reach the proper dimension

Self-contained example:

mazeboard = [[0]*5 for _ in range(5)]
x1 = 7
x2 = 7

old_len = len(mazeboard[0])
# extend the existing rows
for m in mazeboard:
    m += [1]*(x1+1-old_len)
# add rows
mazeboard += [[1]*(x1+1) for i in range(len(mazeboard),x2+1)]

print(mazeboard)

result:

[[0, 0, 0, 0, 0, 1, 1, 1],
  [0, 0, 0, 0, 0, 1, 1, 1],
  [0, 0, 0, 0, 0, 1, 1, 1],
  [0, 0, 0, 0, 0, 1, 1, 1],
  [0, 0, 0, 0, 0, 1, 1, 1],
  [1, 1, 1, 1, 1, 1, 1, 1],
  [1, 1, 1, 1, 1, 1, 1, 1],
  [1, 1, 1, 1, 1, 1, 1, 1]]

so no nested loop, no useless copy, using list multiplication to generate the proper lengths for the lists to add.

Upvotes: 1

Related Questions