I'm currently working on a program that takes a group of lists from a csv file, and groups them together. The program I came up with is:
List_one = []
with open("trees.csv") as f:
skiplines = f.readline()
for line in f:
res = line.split(" ")
List_one.append(res)
for i in List_one:
(i[0]) = (i[0]).rstrip("\n")
print (List_one)
What I get now are a group of lists, but the problem is that these lists are strings and I want them as floats. The lists look like this:
[['1,8.3,70,10.3'], ['2,8.6,65,10.3'], ['3,8.8,63,10.2'], ['4,10.5,72,16.4'], ['5,10.7,81,18.8'], ['6,10.8,83,19.7'], ['7,11.0,66,15.6'], ['8,11.0,75,18.2'], ['9,11.1,80,22.6'], ['10,11.2,75,19.9'], ['11,11.3,79,24.2'], ['12,11.4,76,21.0'], ['13,11.4,76,21.4'], ['14,11.7,69,21.3'], ['15,12.0,75,19.1'], ['16,12.9,74,22.2'], ['17,12.9,85,33.8'], ['18,13.3,86,27.4'], ['19,13.7,71,25.7'], ['20,13.8,64,24.9'], ['21,14.0,78,34.5'], ['22,14.2,80,31.7'], ['23,14.5,74,36.3'], ['24,16.0,72,38.3'], ['25,16.3,77,42.6'], ['26,17.3,81,55.4'], ['27,17.5,82,55.7'], ['28,17.9,80,58.3'], ['29,18.0,80,51.5'], ['30,18.0,80,51.0'], ['31,20.6,87,77.0']]
As you guys can see I also can't use float() on list one either, because the list is a whole string on its own. Is there a way I can split the lists by indexing so I get:
['1', '8.3', '70', '10.3'].....
Any help is welcome.
"line.split(',')" split the string with "," and returns list.
for string '1,8.3,70,10.3' it will return [1, 8.3, 70, 10.3]
You can split the strings by the commas if you want. You should probably do everything before you append them to List_one though.
res = [float(x) for x in line.split(" ")[0].split(",")]
List_one.append(res)
Does this work how you want it to? Sorry I'm not sure what format the input is in so I'm kind of guessing
You could say:
res = line.split(" ")
# map takes a function as the first arg and a list as the second
list_of_floats = list(map(lambda n: float(n), res.split(",")))
# then you can
List_one.append(list_of_floats)
Which will still give you a nested list because you are pushing a list during each iteration of for line in f:, but each list would at least be floats as you've specified.
If you wanted to just get one flat list of floats instead of doing the initial line.split(' ') you could use regex to split the line read from the csv:
import re # at the top of your file
res = re.split(r'[\s\,]', line)
list_of_floats = list(map(lambda n: float(n), res))
List_one.append(list_of_floats)
This might help:
l =[['1,8.3,70,10.3'], ['2,8.6,65,10.3'], ['3,8.8,63,10.2'], ['4,10.5,72,16.4']]
l2 =[]
for x in l:
a =x[0].split(",")
l2.append(a)
print(l2)
Enjoy!
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()
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.
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.
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]
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(' ').
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)
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)
How does one ignore lines in a file?
Example:
If you know that the first lines in a file will begin with say, a or b and the remainder of lines end with c, how does one parse the file so that lines beginning a or b are ignored and lines ending c are converted to a nested list?
What I have so far:
fname = raw_input('Enter file name: ')
z = open(fname, 'r')
#I tried this but it converts all lines to a nested list
z_list = [i.strip().split() for i in z]
I am guessing that I need a for loop.
for line in z:
if line[0] == 'a':
pass
if line[0] == 'b':
pass
if line[-1] == 'c':
list_1 = [line.strip().split()]
The above is the general idea but I am expert at making dead code! How does one render it undead?
startswith can take a tuple of strings to match, so you can do this:
[line.strip().split() for line in z if not line.startswith(('a', 'b'))]
This will work even if a and b are words or sentences not just characters.
If there can be cases where lines don't start with a or b but also don't end with c you can extend the list comprehension to this:
[
line.strip().split()
for line in z if line.endswith('c') and not line.startswith(('a', 'b'))
]
One very general approach is to "filter" the file by removing some lines:
import itertools
zlist = [l.strip.split() for l in itertools.ifilter(lambda line: line[0] not in 'ab', z)]
You can use itertools.ifilter any time you want to "selectively filter" an iterable, getting another iterable which only contains those items which satisfy some predicate -- which is why I say this approach is very general. itertools has a lot of great, fast tools for dealing with iterables in a myriad way, and is well worth studying.
A similar but syntactically simpler approach, which suffices in your case (and which therefore I would recommend due to the virtue of simplicity), is to do the "filtering" with an if clause in the listcomp:
zlist = [l.strip.split() for l in z if l[0] not in 'ab']
You can add if conditions to list comprehensions.
z_list = [i.strip().split() for i in z if i[-1] == 'c']
or
z_list = [i.strip().split() for i in z if (i[0] <> 'a' and i[0] <> 'b')]
One way to do it is to replace 'pass' with 'continue'. This will continue to the next line in the file without doing anything. You will also need to append line to list_1
if line[-1] == 'c':
list_1.append([line.strip().split()])
f=open("file")
for line in f:
li=line.strip()
if not li[0] in ["a","b"] and li[-1]=="c":
print line.rstrip()
f.close()
For those interested in the solution.
And also, another question!
Example file format:
c this is a comment
p m 1468 1 267
260 32 0
8 1 0
Code:
fname = raw_input('Please enter the name of file: ')
z = open(fname, 'r')
required_list = [line.strip().split() for line in z if not line.startswith(('c', 'p'))]
print required_list
Output:
[['260', '32', '0'], ['8', '1', '0']]
Any suggestions on how to convert the strings in the lists to integers and perform arithmetic operations?
Pseudocode to illustrate:
#for the second item in each sublist
#if sum is > than first number in second line of file
#pass
#else
#abort/raise error
Cheers folks for your suggestions so far,
Seafoid.
#Nadia, my day seems a little more worthwhile now! I spent hours (days even) trying to crack this solo! Thanks!