5
votes

So like the title says im starting to learn some python and im having trouble picking up on this technique. What I need to accomplish is to read in some numbers and store them in a list. The text file looks like the following:

0 0 3 50

50 100 4 20

Basically these are coordinates and directions to be used for python's turtle to make shapes. I got that part down the only problem is getting them in a correct format. So what I can not figure out is how to get those numbers from the file into [ [0, 0, 3, 50], [50, 100, 4, 20] ] A list, with each four coordinates being a list in that one big list.

Heres my attempt but it as I said I need some help - thank you.

polyShape=[]
infile = open(name,"r")
num = int(infile.readline(2))
while num != "":
    polyShape.append(num)
    num = int(infile.readline(2))
infile.close()
6

6 Answers

13
votes
with open('data.txt') as f:
    polyShape = []
    for line in f:
        line = line.split() # to deal with blank 
        if line:            # lines (ie skip them)
            line = [int(i) for i in line]
            polyShape.append(line)

will give you

[[0, 0, 3, 50], [50, 100, 4, 20]]

This will work with a file that contains blank lines (or not).

Using the with construct will close the file for you automatically when you are done, or an exception is encountered.

3
votes

Assuming there isn't actually a blank line in your input file:

with open(name, "r") as infile:
    polyShape = [map(int, line.split()) for line in infile]

Explanation: map(int, line.split()) splits each line and converts each part to an int. The [X for Y in Z] construct is a list comprehension that in turn maps the map over all lines of the file and returns its results in a list.

If you find this too complicated for now, then the map(int, line.split()) is the main take-home message.

2
votes
with open('data.txt') as f:
    lis=[map(int,x.split()) for x in f if x.strip()]   # if x.strip() to skip blank lines

   #use list(map(int,x.split()))  in case of python 3.x

this is how map() works:

>>> map(int,'1 2 3 4'.split())
[1, 2, 3, 4]
1
votes

One-liner:

[ [int(x) for x in line.split(' ')] for line in open(name,'r').readlines() if line.strip()]

but the readlines part is probably not a great idea.

I'm quite sure that [int(x) for x in ... ] is faster than using map as in other suggested solutions.

Edit

Thanks to Blender : no need for .readlines, which is cool, so we just have :

[ map(int, line.split()) for line in open(name,'r') if line.strip()]

I also used map(int, ) because it's actually faster, and also you can use just line.split() instead of line.split(' ').

1
votes

Iterating over the file would be the easiest way:

poly_shape = []

with open(name, 'r') as handle:
    for line in handle:
        if not line.strip():
            continue  # This skips blank lines

        values = map(int, line.split())
        poly_shape.append(values)
0
votes

I do not recommend using append for a big array. It's 50 time slower than creating a zero array and assigning values to it.

import numpy
fname = "D:\Test.txt";
num_lines = sum(1 for line in open(fname));
array = numpy.zeros((num_lines,4));
k = 0;
with open(fname, "r") as ins:
    for line in ins:
        a =[int(i) for i in line.split(' ')];;
         array[k,0:4] =a;
         k = k+1;
print(array)