2
\$\begingroup\$

I am using the below code in Python to input a N*N matrix in its original form:

n = int(input())
l=[]
for i in range(n):
    x=input().split()
    c=[]
    for j in range(n):
        c.append(int(x[j]))
    l.append(c)

print(l)

Here's the output:

2 #input n

1 3 #input row

1 5. # input another row

[[1, 3], [1, 5]] # final matrix

How can this code be improved? Is there a better way to take a matrix as input?

\$\endgroup\$

migrated from stackoverflow.com Apr 30 at 16:21

This question came from our site for professional and enthusiast programmers.

  • \$\begingroup\$ The for loop can be a single line: l.append([int(x) for x in input().split()]) \$\endgroup\$ – John Gordon Apr 30 at 15:46
  • \$\begingroup\$ Have a look at this question for some ideas: stackoverflow.com/questions/32466311/… \$\endgroup\$ – sekky Apr 30 at 15:48
  • \$\begingroup\$ @JohnGordon than how can I incorporate the below for loop \$\endgroup\$ – Akshit Aggarwal Apr 30 at 15:59
1
\$\begingroup\$

The two main datatypes for storing matrices in Python (other that the nested list that you use here) are Numpy arrays and Pandas dataframes. Both Numpy and Pandas support reading files, for instance see these links for Numpy and Pandas. You can open a spreadsheet program such as Excel, write the values there, save it as a CSV, then read the CSV into Python.

If you want to input from the console, you should give some output to let the user what you're expecting them to do. As it stands, running your program results in the program just sitting there with no indication what it's waiting for. If you know what format the user will be using, you can simplify the reading quite a bit. If the user simply enters the nested list (in this case [[1,3],[1,5]]), then doing eval on it will turn it from a string to a nested list. However, doing eval on arbitrary input from the user is dangerous. A safer alternative is given here.

\$\endgroup\$
1
\$\begingroup\$

Since the number of rows is to be equal to the number of columns, you can simply get the number of columns from the first input and stop taking input when the user enters the same number of rows:

l = []
while not l or len(l) < len(l[0]):
    l.append(list(map(int, input().split())))

so that given an input of:

2 3 4
1 2 3
5 6 7

l would become:

[[2, 3, 4], [1, 2, 3], [5, 6, 7]]
\$\endgroup\$
1
\$\begingroup\$

Is there a better way to take a matrix as input?

Well, if by "better" you mean fewer lines of code, then I have the solution for you!

The Solution

(lambda N: [[int(x) for x in input().split()[:N]] for _ in range(N)])(int(input("Enter N: ")))

This one-liner is almost reminiscent of a Code Golf contest entry, or one of JavaScript's immediately invoked function expressions.

The Explanation

It's pretty hard to understand what all is going on in that one line, so let's dissect it piece-by-piece.

First, we'll note the general structure is (lambda expression)(argument), so that means we are defining an anonymous function and immediately calling it. The argument is the easier part, so let's start there.

What is the argument?

The argument is simply the size N of the matrix, where we convert the user input (prompted by "Enter N: ") to an integer.

What is the lambda expression?

If you're not already familiar with Python's lambda expressions, these are how you can create anonymous functions that take in certain parameters and return a value. In this case, we are taking in the parameter N and returning a 2D list (our matrix) formed via a "list comprehension."

If you don't know list comprehensions, what they do is construct lists of the form [a for b in c]. That is equivalent to the following:

L = []
for b in c:
    L.append(a)
return L

Another note to make is that when _ is used as the loop variable, that just means we don't intend to use it later on. In this case, the row number is unimportant.

Finally, when we say [int(x) for x in input().split()[:N]], this means we split the input row into integers and take only the first N elements, which (for better or worse) means that we can ignore any extra input on each line beyond the N integers we seek.

Conclusion

All things considered, this is probably not the way to do things. For evidence, consult The Zen of Python. This particular code is fairly ugly, complicated, nested, dense, and unreadable, even though it is short. However, I thought it was worth mentioning because it is a good demonstration of how short a useful Python script can be (and of lambda expressions and list comprehensions, for those who have not yet been introduced).

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.