I'm new to python.
I have two files, one that contains symbols (words) and another that is a map file.
Both files are text files. The map file does contain form feeds.
I want to find the line in the map file that is one above the line that contains
a symbol in the map file.
I have the following code.
Osymbolfile="alistofsymbols"
mapfile="amapfile"
maplines = (line.rstrip('\n\f') for line in open(mapfile))
for line in Osymbolfile:
line = (line.rstrip('\n') )
print "line= ",line
linecount = 0
for index, scanline in enumerate(maplines):
if line in scanline:
print "scanline=",scanline
print "index=",index
else:
linecount = linecount + 1
print "= ",linecount
After print "index=",index ,I've tried print maplines[index-1], but I get an error.
How do I obtain the line above the index'th line in maplines?
Your maplines object is a generator expression; these produce items on demand and are not indexable.
You could use a list comprehension instead:
maplines = [line.rstrip('\n\f') for line in open(mapfile)]
Now you have a indexable list object instead. Even better, you can now loop over this object multiple times; you cannot do that with a generator.
The proper way to handle your case however, is to store the previous line only:
with open(mapfile) as maplines:
prev = None
for line in maplines:
if something in line:
return prev
prev = line
Related
I have a CSV file that contains matrix:
1,9,5,78
4.9,0,24,7
6,2,3,8
10,21.4,8,7
I want to create a function that returns list of lists:
[[1.0,9.0,5.0,78.0],[4.9,0.0,24.0,7.0],[6.0,2.0,3.0,8.0],[10.0,21.4,8.0,7.0]]
this is my attempt:
fileaname=".csv"
def get_csv_matrix(fileaname):
mat=open(fileaname,'r')
mat_list=[]
for line in mat:
line=line.strip()
mat_line=[line]
mat_list.append(mat_line)
return mat_list
but I get list of lists with one string:
[['1,9,5,78'], ['4.9,0,24,7'], ['6,2,3,8'], ['10,21.4,8,7']]
how can i turn the lists of strings to lists of floats?
mat_line = [line]
This line just takes the line as a single string and makes it into a one element list. If you want to separate it by commas, instead do:
mat_line = line.split(',')
If you want to also turn them into numbers, you'll have to do:
mat_line = [float(i) for i in line.split(',')]
I find it easier to read a list comprehension than a for loop.
def get_csv_matrix(filename):
with open(filename) as input_file:
return [[float(i) for i in line.split(',')] for line in input_file]
print (get_csv_matrix("data.csv"))
The above function opens a file (I use with to avoid leaking open file descriptors), iterates over the lines, splits each line, and converts each item into a floating-point number.
Try
fileaname=".csv"
def get_csv_matrix(fileaname):
mat=open(fileaname,'r')
mat_list=[]
for line in mat:
line=line.strip()
mat_line=line.split(",")
for i in mat_line:
i_position = line.index(i)
line[i_position] = float(i)
mat_list.append(mat_line)
return mat_list
If any object in mat_line isn't an integer, you will come up with an error, so I suggest you create a validation method to be absolutely sure that it is an integer.
I'm a total noob to Python and need some help with my code.
The code is meant to take Input.txt [http://pastebin.com/bMdjrqFE], split it into seperate Pokemon (in a list), and then split that into seperate values which I use to reformat the data and write it to Output.txt.
However, when I run the program, only the last Pokemon gets outputted, 386 times. [http://pastebin.com/wkHzvvgE]
Here's my code:
f = open("Input.txt", "r")#opens the file (input.txt)
nf = open("Output.txt", "w")#opens the file (output.txt)
pokeData = []
for line in f:
#print "%r" % line
pokeData.append(line)
num = 0
tab = """ """
newl = """NEWL
"""
slash = "/"
while num != 386:
current = pokeData
current.append(line)
print current[num]
for tab in current:
words = tab.split()
print words
for newl in words:
nf.write('%s:{num:%s,species:"%s",types:["%s","%s"],baseStats:{hp:%s,atk:%s,def:%s,spa:%s,spd:%s,spe:%s},abilities:{0:"%s"},{1:"%s"},heightm:%s,weightkg:%s,color:"Who cares",eggGroups:["%s"],["%s"]},\n' % (str(words[2]).lower(),str(words[1]),str(words[2]),str(words[3]),str(words[4]),str(words[5]),str(words[6]),str(words[7]),str(words[8]),str(words[9]),str(words[10]),str(words[12]).replace("_"," "),str(words[12]),str(words[14]),str(words[15]),str(words[16]),str(words[16])))
num = num + 1
nf.close()
f.close()
There are quite a few problems with your program starting with the file reading.
To read the lines of a file to an array you can use file.readlines().
So instead of
f = open("Input.txt", "r")#opens the file (input.txt)
pokeData = []
for line in f:
#print "%r" % line
pokeData.append(line)
You can just do this
pokeData = open("Input.txt", "r").readlines() # This will return each line within an array.
Next you are misunderstanding the uses of for and while.
A for loop in python is designed to iterate through an array or list as shown below. I don't know what you were trying to do by for newl in words, a for loop will create a new variable and then iterate through an array setting the value of this new variable. Refer below.
array = ["one", "two", "three"]
for i in array: # i is created
print (i)
The output will be:
one
two
three
So to fix alot of this code you can replace the whole while loop with something like this.
(The code below is assuming your input file has been formatted such that all the words are split by tabs)
for line in pokeData:
words = line.split (tab) # Split the line by tabs
nf.write ('your very long and complicated string')
Other helpers
The formatted string that you write to the output file looks very similar to the JSON format. There is a builtin python module called json that can convert a native python dict type to a json string. This will probably make things alot easier for you but either way works.
Hope this helps
My program is supposed to take input from the user and read a file with the name input. Read file gets saved into a dictionary called portfolio and from there all I have to do is sort each line in the portfolio into keys and values.
Here's my code.
portfolio = {}
portfolio = file_read() #Reads the file through a function
if file_empty(portfolio) == True or None: #nevermind this, it works
print "The file was not found."
else:
print "The file has successfully been loaded"
for line in portfolio:
elements = line.strip().split(",") #separate lists by comma
print elements[0] #using this to check
print elements[1] #if it works at all
All this does is print the first letter in the first line, which is S. And apparently elements[1] is supposed to be the second letter but index is out of range, please enlighten me what might be wrong.
Thank you.
It looks like file_read() is reading the file into a string.
Then for line in portfolio: is iterating through each character in that string.
Then elements = line.strip().split(",") will give you a list containing one character, so trying to get elements[1] is past the bounds of the list.
If you want to read the whole contents of the file into a string called portfolio, you can iterate through each line in the string using
for line in porfolio.split('\n'):
...
But the more usual way of iterating through lines in a file would be
with open(filename,'r') as inputfile:
for line in inputfile:
....
Got it to work with this code:
for line in minfil :
line = line.strip()
elements = line.split(",")
portfolio[str(elements[0])] = [(int(elements[1]),float(elements[2]), str(elements[3]))]
Hi I already have the search function sorted out:
def searchconfig():
config1 = open("config.php", "r")
b='//cats'
for num, line in enumerate(config1,0):
if b in line:
connum = num + 1
return connum
config1.close()
This will return the line number of //cats, I then need to take the data underneath it put it in a tempoary document, append new data under the //cats and then append the data in the tempoary document to the original? how would i do this? i know that i would have to use 'a' instead of 'r' when opening the document but i do not know how to utilise the line number.
I think, the easiest way would be to read the whole file into a list of strings, work on that list and write it back afterwards.
# Read all lines of the file into a list of strings
with open("config.php", "r") as file:
lines = list(file)
file.close()
# This gets the line number for the first line containing '//cats'
# Note that it will throw an StopIteration exception, if no such line exists...
linenum = (num for (num, line) in enumerate(lines) if '//cats' in line).next()
# insert a line after the line containing '//cats'
lines.insert(linenum+1, 'This is a new line...')
# You could also replace the line following '//cats' like
lines[linenum+1] = 'New line content...'
# Write back the file (in fact this creates a new file with new content)
# Note that you need to append the line delimiter '\n' to every line explicitely
with open("config.php", "w") as file:
file.writelines(line + '\n' for line in lines)
file.close()
Using "a" as mode for open would only let you append ath the end of the file.
You could use "r+" for a combined read/write mode, but then you could only overwrite some parts of the file, there is no simple way to insert new lines in the middle of the file using this mode.
You could do it like this. I am creating a new file in this example as it is usually safer.
with open('my_file.php') as my_php_file:
add_new_content = ['%sNEWCONTENT' %line if '//cat' in line
else line.strip('\n')
for line in my_php_file.readlines()]
with open('my_new_file.php', 'w+') as my_new_php_file:
for line in add_new_content:
print>>my_new_php_file, line
I am basically trying to update a line in saved files with new updated number but it leaves only one line in the file. It feels like its overwriting over entire file rather than updating it. I looked at other questions here, and although they gave me right module to use I can't seem to figure out the problem I am having.
unique = 1
for line in fileinput.input('tweet log.txt', inplace=1):
if tweet_id in line: #checks if ID is unique, if it is not, needs to update it
tweet_fields = line.split(';')
old_count = tweet_fields[-2]
new_count = 'retweet=%d' % (int(tweet_retweet))
line = line.replace(old_count, new_count)
print line
unique = 0
if unique == 1: #if previous if didn't find uniqueness, appends the file
save_file = open('tweet log.txt', 'a')
save_file.write('id='+tweet_id +';'+
'timestamp='+tweet_timestamp+';'+
'source='+tweet_source+';'+
'retweet='+tweet_retweet+';'+'\n')
save_file.close()
I feel like this has a very easy solution but I am clearly missing it.
Thanks in advance!
I think the issue you're having is due to your conditional in the loop over the input. When you use fileinput.input with the inplace=1 argument, it renames the original file adding a "backup" extension (by default ".bak") and redirects standard output to a new file with the original name.
Your loop is only printing the line that you're editing. Because of this, all the non-matching lines are getting filtered out of the file. You can fix this by printing each line you iterate over, even if it doesn't match. Here's an altered version of your loop:
for line in fileinput.input('tweet log.txt', inplace=1):
if tweet_id in line:
tweet_fields = line.split(';')
old_count = tweet_fields[-2]
new_count = 'retweet=%d' % (int(tweet_retweet))
line = line.replace(old_count, new_count)
unique = 0
print line
The only change is moving the print line statement out of the if block.