Skip to content
Advertisement

what’s a better way to read information from TXT and put into list in python

I have a TXT in following form, which is the data for Knapsack problem:

  • 100 in first row represents the total capacity
  • 10 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.

User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement