简体   繁体   中英

reading text file and putting some characters in lists

My objective is to transform this text in a textfile (all in 1 line):

a b s d p
5 4 3 3 2
..........
....pp..s.
........s.
.a......s.
.a.....b..
.a.....b..
.a.....b..
.a.ddd.b..
..........
..........

And have an output: [['a', 'b', 's', 'd', 'p'],[5, 4, 3, 3, 2]] But I get the following error: ship_characters.append(str(char)) MemoryError

Here is my code:

def read_ship_data(game_file):

    ship_characters = []
    ship_sizes = []

    game = open(game_file, 'r')
    for line in game:
        for char in line:
            while char != '.':
                if char.isalpha():
                    ship_characters.append(str(char))
                elif char.isnumeric():
                    ship_sizes.append(int(char))
    return [ship_characters , ship_sizes]

Right now, you are looping infinitely on the first character and appending it to your list. Your while loop will never stop since 'a' != '.' will always be true.

If you just want the 2 first lines and the format will never change, you should use something simpler:

def read_ship_data(game_file):
    with open(game_file, 'r') as file:
        ship_characters = file.readline().strip().split()
        ship_sizes = file.readline().strip().split()
        ship_sizes = [int(i) for i in ship_sizes]

    return [ship_characters, ship_sizes]

You're looping forever:

for char in line:
    while char != '.':
        if char.isalpha():
            ship_characters.append(str(char))
        elif char.isnumeric():
            ship_sizes.append(int(char))

You set the value of char for one iteration through line , then you stay in your while loop as long as that value isn't '.' - but no where in the while loop do you change the value of char . That happens outside of the while loop, when it gets to the next cycle in the for loop.

It seems like you want to remove the while loop and instead have if char != '.': maybe?

Edit: Actually there's no need to catch '.' separately - you're already testing using isalpha() and isnumeric() - note that you want isdigit() if you're in Python 2.x and not using unicode - and a '.' returns False on both of those. So you can do it like this:

for char in line:
    if char.isalpha():
        ship_characters.append(str(char))
    elif char.isnumeric():
        ship_sizes.append(int(char))
    else:
        pass
        #do something for non-letter and non-number values if you want

Others have identified the reason for the memory error: an infinite loop.

Assuming that you require the first 2 lines from the file here is a better way to do it:

def read_ship_data(game_file):
    with open(game_file) as game_file:
        return [line.split() for line in (next(game_file), next(game_file))]

This just reads the first 2 lines from the file (with next(file) ), and splits the lines in a list comprehension, which is returned from the function.

If you need to convert the values from the second line to integers:

def read_ship_data(game_file):
    with open(game_file) as game_file:
        return [next(game_file).split(),  [int(x) for x in next(game_file).split()]]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM