3

I was given an array of strings and I want to split each of the individual strings into separate characters and store them in a separate 2-D array. I wrote the following code:-

# The given array
grid = ['1112', '1912', '1892', '1234']

# Creating a new 2D array
mat = [[None]*len(grid)]*len(grid)
for i in range(0,len(grid)):
    for j in range(0,len(grid)):
        mat[i][j] = grid[i][j]
print(mat)

But doing this gives weird values in my two-dimensional array, mat. Each of the row of the 2D array mat gets printed as ['1','2','3','4'] but this should be the value of the last row only.

I shall be thankful if someone could answer my query.

3 Answers 3

3
mat = [[None]*len(grid)]*len(grid)

This statement is creating a relational 2D array (matrix), so whenever you are updating a line, it will update all the other lines.

You should be using this to create an empty 2D array:

mat = [[None for i in len(grid)] for j in range(len(grid))]

As @marc commented, you can also pass one list comprehension as width = height here

mat = [[None]*len(grid) for _ in range(len(grid))]
Sign up to request clarification or add additional context in comments.

2 Comments

You could safely skip one of the list comprehension steps and use mat = [[None]*len(grid) for i in range(len(grid)].
@Marc Ah yeah, I will add it alongside, if they later need a matrix with a width different from the height, they would still need to do 2 list comprehensions
1

The multiplication to list makes the same reference in memory, code fixed as following:

# The given array
grid = ['1112', '1912', '1892', '1234']

# Creating a new 2D array
# mat = [[None]*len(grid)]*len(grid)
mat = []
for i in range(len(grid)):
    t = []
    for j in range(len(grid)):
        t.append(None)
    mat.append(t)

for i in range(0,len(grid)):
    for j in range(0,len(grid)):
        mat[i][j] = grid[i][j]
print(mat)

1 Comment

This would work but is longer to process than my answer, with list comprehension, which is also more readable
1

I have to agree this is easy to get confused in this problem.

Let's say len(grid) = 2, so we get mat = [[None]*2]*2

Here mat[0] points to the same pobject of mat[1], because *2 is giving two pointers which pointing to the same array. You can use for _ in range(2) instead to create two different objects - [[None]*len(grid) for _ in range(len(grid))]

We can use id to print the object's address to verify:

>>> mat = [[None]*2]*2
>>> id(mat[0])
76447616
>>> id(mat[1])
76447616
>>> grid = [0, 0]
>>> x = [[None]*len(grid) for _ in range(len(grid))]
>>> id(x[0])
76457744
>>> id(x[1])
76391968

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.