Search code examples
pythonarraysallocation

Array preallocation Python


I'm writing a simple code in Python to sort a pre existing array A of dimensions [6][7] to do that I wanted to save the sorted array with a different name let's say B. I've done the following code but doesn't work

B=[[0]*7]*6


For i in range(0,6):
  For j in range(0,7):
    If A[i][j] > 7:
       B[i][j] = 1
    Else 
       B[i][j] = 0

The problem is in the preallocation of array B indeed if I print it it doesn't give the result I need, on the other hand if create B from scratch in a way like this it works

B=[
[0,0,0,0,0,0,0],
.
.
.
.
.
.
]

Can someone explain me why? Thank you very much.


Solution

  • The problem is this:

    When you do: (I'm going to use lowercase variable names since you seem to have some accidental capitalization going on in your question)

    b=[[0]*7]*6
    

    what happens is that every row of b is the same object. It's as though you did this:

    b = []
    row = [0]*7
    for _ in range(6):
        b.append(row)
    

    What this means:

    >>> import pprint
    >>> b=[[0]*7]*6
    >>> pprint.pprint(b)
    [[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]]
    >>> b[3][2] = 1
    >>> pprint.pprint(b)
    [[0, 0, 1, 0, 0, 0, 0],
     [0, 0, 1, 0, 0, 0, 0],
     [0, 0, 1, 0, 0, 0, 0],
     [0, 0, 1, 0, 0, 0, 0],
     [0, 0, 1, 0, 0, 0, 0],
     [0, 0, 1, 0, 0, 0, 0]]
    >>> b[4][3] = 2
    >>> pprint.pprint(b)
    [[0, 0, 1, 2, 0, 0, 0],
     [0, 0, 1, 2, 0, 0, 0],
     [0, 0, 1, 2, 0, 0, 0],
     [0, 0, 1, 2, 0, 0, 0],
     [0, 0, 1, 2, 0, 0, 0],
     [0, 0, 1, 2, 0, 0, 0]]
    

    So what you need is a different object for each row of b. There are a few ways to get this. Any of the following should work:

    b = []
    for _ in range(6):
      b.append([0]*7)
    

    or

    b = [[0]*7 for _ in range(6)]
    

    or

    import copy
    b = []
    row = [0]*7
    for _ in range(6):
        b.append(copy.copy(row))