3

I want to create a random size list in Python.

Here's my code:

row_num = int(input('Please enter matrix row number:'))
colum_num = int(input('please enter matrix column number:'))
a = [[0]*row_num]*colum_num
print("Please enter matrix: ")
for i in range(colum_num):
    for j in range(row_num):
        a[i][j]=int(input())

print(a)

For example, I want to generate a 2*3 matrix, here's my outcome:

Please enter matrix row number:2
please enter matrix column number:3
Please enter matrix: 
1
2
3
4
5
6
[[5, 6], [5, 6], [5, 6]]

I expect the result to be [[1,2],[3,4],[5,6]].

Why is the result the last element?

3
  • full answers already given, but key is try: a = [[0]*3]*3 #n print(a) #n a[1][1] = "Same" #n print(a) #n Commented Oct 2, 2015 at 7:53
  • @Joop, the same problem will remain due to the reasons I gave in my answer. Try running it in IDLE. Commented Oct 2, 2015 at 8:06
  • I was not pretending to give answer just succinctly stating problem as you did in your answer Commented Oct 2, 2015 at 13:30

2 Answers 2

2

The problem in your code is that when you do something like that:

a = [[0] * row_num] * colum_num

you create colum_num links to list [[0] * row_num]. When you change one of the lists (in your for), others get changed too. You can run following code to see what I mean

a = [1,2,3]
b = [a] * 3
print(b)
a[1] = 10
print(b)

the output will be [[1, 2, 3], [1, 2, 3], [1, 2, 3]] and [[1, 10, 3], [1, 10, 3], [1, 10, 3]] because b is just 3 links to a.

There are multiple ways of creating new lists and not copies, e.g. indexing the full list

b = [a[:]] * 3 

or using copy module

import copy
b = [copy.copy(a)] * 3

or using generator expressions to create multiple lists that are alike (full of 0), but are different objects, like sgbirch suggested.

a = [[0 for x in range(column_num)] for y in range(row_num)]

By the way, there is no pont of creating a list full of 0, you can just do something like that:

row_num = int(input('Please enter matrix row number:'))
column_num = int(input('please enter matrix column number:'))
a = [[int(input()) for x in range(column_num)] for y in range(row_num)]

it also is probably simpler for user to input the matrix row by row.

a = [[int(x) for x in input('Input row № {} ({} numbers): '.format(y + 1, column_num)).split()] for y in range(row_num)]
Sign up to request clarification or add additional context in comments.

Comments

2

You have to create a list which contains a list of lists.

# Create a list containing lists initialised to 0
a = [[0 for x in range(row_num)] for x in range(column_num)]

Your code is actually producing a colum_length list whose elements all contain a reference to the same row_num length lists. You can see this in the following code based on yours:

row_num = 2                                                                     
colum_num = 3                                                                   

a = [[0 for x in range(row_num)] for x in range(colum_num)]                     
b = [[0]*row_num]*colum_num                                                     

assert a == b                                                                   

count = 0                                                                       
for i in range(colum_num):                                                      
    for j in range(row_num):                                                    
        a[i][j] = count                                                         
        b[i][j] = count                                                         
        print "a",a                                                             
        print "b",b                                                             
        print                                                                   
        count += 1

Which produces:

a [[0, 0], [0, 0], [0, 0]]
b [[0, 0], [0, 0], [0, 0]]

a [[0, 1], [0, 0], [0, 0]]
b [[0, 1], [0, 1], [0, 1]]

a [[0, 1], [2, 0], [0, 0]]
b [[2, 1], [2, 1], [2, 1]]

a [[0, 1], [2, 3], [0, 0]]
b [[2, 3], [2, 3], [2, 3]]

a [[0, 1], [2, 3], [4, 0]]
b [[4, 3], [4, 3], [4, 3]]

a [[0, 1], [2, 3], [4, 5]]
b [[4, 5], [4, 5], [4, 5]]

An alternative approach might be to use numpy which provides ready made array primitives:

import numpy
# Returns a new array of given shape and type, filled with zeros.
a = numpy.zeros((2, 3), dtype=numpy.int)
print a
[[0 0 0]
 [0 0 0]]

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.