I have a TXT in following form, which is the data for Knapsack problem:
100in first row represents the total capacity10in first row represent the number of items- Then each row contains the value and weight for each item. For example, the second row
9 46represents an item with 9 in value and 46 in weight.
100 10n 9 46n 28 31n 15 42n 13 19n 31 48n 36 11n 13 27n 42 17n 28 19n 1 31
I use the code below to read the information and put it into separate list.
with open(path) as f:
capacity,total_number = f.readline().split(' ')
capacity = int(capacity)
total_number = int(total_number)
value_list = [int(x.split(' ')[0]) for x in f.readlines()]
f.seek(0)
next(f)
weight_list = [int(x.split(' ')[1]) for x in f.readlines()]
assert total_number==len(weight_list)==len(value_list)
But it kinds feel redundant in a way.
Ccould anyone help me with improvements on that?
Advertisement
Answer
- You can use a list comprehension to cast the entire line to integers at once.
- You can use the
zip(*...)idiom to transpose a list; here, to transpose a list of[(value, weight), (value, weight), (value, weight)]pairs to[value, value, value...]and[weight, weight, weight...].
with open(path) as f:
capacity, total_number = [int(num) for num in f.readline().split()]
values_and_weights = [[int(num) for num in l.split()] for l in f.readlines()]
value_list, weight_list = zip(*values_and_weights)
In fact, since all lines are just number pairs,
with open(path) as f:
data = [[int(num) for num in l.split()] for l in f.readlines()]
capacity, total_number = data.pop(0) # remove and unpack first line
value_list, weight_list = zip(*data)
is even more succinct.