I have a TXT in following form, which is the data for Knapsack problem:
100
in first row represents the total capacity10
in first row represent the number of items- Then each row contains the value and weight for each item. For example, the second row
9 46
represents 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.