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)
Related
For a school assignment
we want to convert every item in the list to be an int using the int(val) function. This will involve first reading in the file, loading all the lines, and then looping through all lines building a second list of ints (use lst). You should return the list of ints
but I don't know how to do it.
This is what I have so far.
def file_int_list(file):
with open(file, 'r+') as f:
lst = []
lines = f.readlines()
for rows in lines:
lst.append(rows)
return lst
lst = []
lines = f.readlines()
for rows in lines:
lst.extend(list(map(int, rows.split(' '))))
return lst
I have a file with text with only 0's and 1's. No space between them. Example:
0101110
1110111
I would like to read a character at a time and place them as a single element in a list of integers.
My code:
intlist = []
with open('arq.txt', 'r') as handle:
for line in handle:
if not line.strip():
continue
values = map(int, line.split())
intlist.append(values)
print intlist
handle.close()
My result:
[[101110], [1110111]]
Like if I transform the 0101110 in intlist = [0,1,0,1,1,1,0,1,1,1,0,1,1,1]. (without '\n')
You just need two changes. The first is, when you're making values, you need to take each individual character of the line, instead of the entire line at once:
values = [int(x) for x in line.strip() if x]
Now, if you run this code on its own, you'll get [[1, 0, ...], [1, 1, ...]]. The issue is that if you call list.append with another list as an argument, you'll just add the list as an element. You're looking for the list.extend method instead:
intlist.extend(values)
Your final code would be:
intlist = []
with open('arq.txt', 'r') as handle:
for line in handle:
if not line.strip():
continue
values = [int(x) for x in line.strip() if x]
intlist.extend(values)
print intlist
If all you have is numbers and linefeeds, you can just read the file, remove the linefeeds, map the resulting string to integers, and turn that into a list:
with open('arq.txt') as handle:
intlist = list(map(int, handle.read().replace('\n', '')))
print intlist
Here's one way you can do it. You also don't need to use handle.close() the context manager handles closing the file for you.
intlist = []
with open('arq.txt', 'r') as handle:
for line in handle:
if not line.strip():
continue
intlist[:] += [int(char) for i in line.split() for char in i]
print(intlist)
Use strip() for delete \n and filter with bool for deleting empty strings:
with open('test.txt') as f:
lines = map(lambda x: x.strip(), filter(bool, f))
print [int(value) for number in lines for value in number]
One possibility:
intlist = []
with open('arq.txt', 'r') as handle:
for line in handle:
for ch in line.strip():
intlist.append (ch)
print intlist
I am a python newbie.
I want to read a text file which reads something like this
1345..
245..
..456
and store it in a list of lists of integers. I want to keep the numbers and replaces the periods by 0s.How do i do it?
EDIT:
Apologize for the ambiguous output spec
p.s I want the output to be a list of list
[ [1,3,4,5,0,0],
[2,4,5,0,0],
[0,0,4,5,6]]
with open('yourfile') as f:
lst = [ map(int,x.replace('.','0')) for x in f ]
Which is the same thing as the following nested list-comp:
lst = [ [int(val) for val in line.replace('.','0')] for line in f]
Here I used str.replace to change the '.' to '0' before converting to an integer.
with open(file) as f:
lis=[[int(y) for y in x.replace('.','0').strip()] for x in f]
Here's an answer in the form of classic for loops, which is easier for a newbie to understand:
a_list = []
l = []
with open('a') as f:
for line in f:
for c in line.rstrip('\n').replace('.', '0'):
l.append(int(c))
a_list.append(l)
#next line
l = []
print a_list
I have a file format like this:
9 8 1
3 4 1
...
...
Now, I want to get each line as three integers.
When I used
for line in f.readlines():
print line.split(" ")
The script printed this:
['9', '8', '1\r\n']
['3', '4', '1\r\n']
...
...
How can I get each line as three integers?
Using the code you have and addressing your specific question of how to convert your list to integers:
You can iterate through each line and convert the strings to int with the following example using list comprehension:
Given:
line =['3', '4', '1\r\n']
then:
int_list = [int(i) for i in line]
will yield a list of integers
[3, 4, 1]
that you can then access via subscripts (0 to 2). e.g.
int_list[0] contains 3,
int_list[1] contains 4,
etc.
A more streamlined version for your consideration:
with open('data.txt') as f:
for line in f:
int_list = [int(i) for i in line.split()]
print int_list
The advantage of using with is that it will automatically close your file for you when you are done, or if you encounter an exception.
UPDATE:
Based on your comments below, if you want the numbers in 3 different variables, say a, b and c, you can do the following:
for line in f:
a, b, c = [int(i) for i in line.split()]
print 'a = %d, b = %d, c = %d\n' %(a, b, c)
and get this:
a = 9, b = 8, c = 1
This counts on there being 3 numbers on each line.
Aside:
Note that in place of "list comprehension" (LC) you can also use a "generator expression" (GE) of this form:
a, b, c = (int(i) for i in line.split())
for your particular problem with 3 integers this doesn't make much difference, but I show it for completeness. For larger problems, LC requires more memory as it generates a complete list in memory at once, while GE generate a value one by one as needed. This SO question Generator Expressions vs. List Comprehension will give you more information if you are curious.
with open("myfile.txt") as f:
for line in f:
int_list = [int(x) for x in line.split()]
You don't say what you want to do with the list of integers, there may be a better way to iterate over them, depending.
If you "need the values as three different variables," then"
a, b, c = int_list
though you could also use:
int_list[0]
int_list[1]
int_list[2]
as desired.
line.strip().split(" ")
would do.
more complete, with all lines still intact in one large string:
data = f.read().strip() # loose final \n
[ int(x.split(" ")) for x in data.split('\n')]
would give you a list with answers you want for each line.
If you wanna store the integers in three variables :
with open('data1.txt') as f:
for line in f:
a,b,c=(int(x) for x in line.split())
print a,b,c
output:
9 8 1
3 4 1
This block of code should solve your problem:
f = open(filepath)
for line in f:
intList = map(int, line.strip().split())
print intList
f.close()
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!