-1

Python 3.7 question.

I do have a file looking like this: 1 10 10 10 3 25 29 10 52 55 30 70 70 20 0

where 1 shows there will be 1 line coming, 3 shows 3 will come, 0 marks end of file. How to achieve this?

I've tried

def read_each_course(filename):
    with open(filename, 'r') as f:
        lines = []
        content = f.readlines()
        lines += [x.rstrip() for x in content]
    for i in lines:
        while True:
            if str(i).count(" ") == 0:
                lines_to_read = int(i)
                break
        return lines_to_read, next(i)

but that won't work I get

TypeError: 'str' object is not an iterator
 for the next(i).

My idea was to get a list of lists as the items like: [[1, [10, 10, 10]], [3, [25, 29, 10], [52, 55, 30], [70, 70, 20]]]

BUT, I am unsure if that design is a good idea in general? Or should it then be rather a single linked list as the ultimate goal is that as the 3 numbers are coordinates I'll have to only use the next item such as x2-x1, y2-y1, penalty if left out (additional cost) where total cost is the hyp. of the xy triangle which is fine I can calculate that.

Pratik
  • 1,351
  • 1
  • 20
  • 37
batlin010
  • 15
  • 4
  • What do you expect `next(i)` to do? As the `TypeError` says, strings are not iterators -- writing e.g. `next('hello')` makes no sense. – Brian61354270 Mar 17 '20 at 16:56

2 Answers2

0

this code should do the tricks, for your design question I have no idea it seems to me to be opinion-based. So I will focus on the code.

In your code lines is a list, and i is an element of this list. you calling next on one of the list elem, not on the list here. I have to admit that I do not understand the logic of your code. So I cannot really help.

def read_each_course(filename):

    result = []
    current = []
    with open(filename) as f_in:

        for line in f_in:  # loop  over the file line by line

            spt = line.strip().split()  # split
            if len(spt) == 1: # one elem

                if current: # not the first one
                    result.append(current)
                    current = []

                if spt[0] == 0: # end of file
                    break

                current.append(int(spt[0]))

            else:
                current.append(list(map(int, spt)))

    return result
RomainL.
  • 997
  • 1
  • 10
  • 24
  • in the code snippet at the end spt is a list not a string so cannot be converted to an int and it returns an error of `TypeError: int() argument must be a string, a bytes-like object or a number, not 'list'` and even if I do `current.append(list(map(int(str(spt)))))` I get `ValueError: invalid literal for int() with base 10: "['50', '50', '20']"` so it didn't work for me – batlin010 Mar 17 '20 at 17:33
  • Logic would be that I do have an algorithm to calculate shortest path between nodes of a graph consisting from above numbers given. Each graph starts with a single length int - as like '3' and the numbers for example 25 29 10 are coordinates to go from 0 0 0 to xy + penalty if I jump ahead and skip it (additional cost) and the last coordinate is 100 100 10. So if I take from 0 0 0 to 25 29 10 there is no penalty, but if I take 0 0 0 then 52 55 30, I get 10 penalties. The end is always 100 100 10. I have the algorithm for optimal route, just I am unsure about which data structure to use. – batlin010 Mar 17 '20 at 19:00
  • 1
    This is an another question and should have its own post. – RomainL. Mar 18 '20 at 07:24
0

This revision of the answer by RomainL simplifies the logic.

It makes use of iterators to parse the file.

def read_each_course(filename):

    result = []
    with open(filename) as f:
        it = iter(f)
        while True:
            count = int(next(it))

            if count == 0:         # Found the stop marker
                break

            current = [count]
            for _ in range(count):
                current.append([int(v) for v in next(it).strip().split()])
            result.append(current)
    return result


print(read_each_course("file2.txt"))

Output as required.

quamrana
  • 37,849
  • 12
  • 53
  • 71