Not sure why Python readlines() doesn't work here

693 views Asked by At

Hi I have a block of code here, intending to read the input into variables:

if __name__ == "__main__":
    data = list(map(int, sys.stdin.readlines().split()))
    n, capacity = data[0:2]
    values = data[2:(2 * n + 2):2]
    weights = data[3:(2 * n + 2):2]
    opt_value = get_optimal_value(capacity, weights, values)
    print("{:.10f}".format(opt_value))

Then the self-defined get_optimal_value(capacity, weights, values) will be executed. Input example:

3 50
60 20
100 50
120 30

It is supposed to achieve the following:

n = 3
capacity = 50
values = [60,100,120]
weights = [20,50,30]

However, the code doesn't proceed after I type in the above input numbers and gives me no result. That means the numbers are not read into the variables and lists are not formulated. I tried my code into an automated error checker; it tells me:

AttributeError: 'list' object has no attribute 'split'

Why is this and how should I modify my code?

Additional question: does the number reading automatically knows where to stop, i.e. when it detects space and no following numbers? I assume the code will execute the function and calculate the result right after it reads all the input data, is that correct in terms of process? I feel like lacking a 'step' to notify the code to 'calculate' after typing in the inputs.

2

There are 2 answers

0
myaut On

readlines returns list which doesn't have method split (it is a method of str object which represents a single line), so your code is equivalent to this:

l = sys.stdin.readlines()   # ["0 1\n", "2 3\n"]
l.split()

If you wish to apply split() to each line, you should add another map call our use list or generator comprehension, i.e.

data = list(map(int, map(lambda line: line.split(), sys.stdin.readlines()))
data = list(map(int, line.split() for line in sys.stdin.readlines()))

Or use foreach:

data = []
for line in sys.stdin:
     data.append(map(int, line.split()))
0
clemens On

readlines() returns a list of strings, and split() is only defined for strings. If you want return the input as a list of list with two ints each, you must apply to the elements of the list:

[map(int, x.split(" ")) for x in sys.stdin.readlines().split()]