How to insert lines in file if not already present? - python

So, I have textfile with multiple lines:
orange
melon
applez
more fruits
abcdefg
And I have a list of strings that I want to check:
names = ["apple", "banana"]
Now I want to go through all the lines in the file, and I want to insert the missing strings from the names list, if they are not present. If they are present, then they should not be inserted.
Generally this should not be to difficult but taking care of all the newlines and such is pretty finicky. This is my attempt:
if not os.path.isfile(fpath):
raise FileNotFoundError('Could not load username file', fpath)
with open(fpath, 'r+') as f:
lines = [line.rstrip('\n') for line in f]
if not "banana" in lines:
lines.insert(0, 'banana')
if not "apple" in lines:
lines.insert(0, 'apple')
f.writelines(lines)
print("done")
The problem is, my values are not inserted in new lines but are appended.
Also I feel like my solution is generally a bit clunky. Is there a better way to do this that automatically inserts the missing strings and takes care of all the newlines and such?

You need to seek to the first position in the file and use join to write each word into a new line, to overwrite its contents:
names = ["apple", "banana"]
with open(fpath, 'r+') as f:
lines = [line.rstrip('\n') for line in f]
for name in names:
if name not in lines:
# inserts on top, elsewise use lines.append(name) to append at the end of the file.
lines.insert(0, name)
f.seek(0) # move to first position in the file, to overwrite !
f.write('\n'.join(lines))
print("done")

First get a list of all the usernames in your file by using readlines() and then use list comprehension to identify the missing usernames from your names list.
Create a new list and write that one to your file.
names = ["apple", "banana"]
new_list = List()
with open(fpath, 'r+') as f:
usernames = f.readlines()
res = [user for user in usernames if user not in names]
new_list = usernames + res
with open(fpath, 'r+') as f:
for item in new_list:
f.write("%s\n" % item)

file_name = r'<file-path>' # full path of file
names = ["apple", "banana"] # user list of word
with open(file_name, 'r+') as f: # opening file as object will automatically handle all the conditions
x = f.readlines() # reading all the lines in a list, no worry about '\n'
# checking if the user word is present in the file or not
for name in names:
if name not in x: # if word not in file then write the word to the file
f.write('\n'+name )

Related

why do string.strip() function removed the character i want in some words and remove none in others

i am trying to remove the '\n' characters a string because when i read the lines from a file it include the '\n' characters!!
input:
with open('names.txt', mode='r') as file:
list_of_names = file.readlines()
print(list_of_names)
for name in list_of_names:
list_of_names.remove(name)
name = name.strip('\n')
list_of_names.append(name)
print(list_of_names)
output:
['Aang\n', 'Zuko\n', 'Appa\n', 'Katara\n', 'Sokka\n', 'Momo\n', 'Uncle Iroh\n', 'Toph']
['Zuko\n', 'Katara\n', 'Momo\n', 'Toph', 'Appa', 'Uncle Iroh', 'Sokka', 'Aang']
Because you are modifying the list while iterating over it, halfway through the loop, list_of_names.remove(name) is trying to remove the wrong element. This is also why the order of the list changes. This is unnecessarily complex.
Instead of modifying the old list, consider simply appending to a new, empty list.
with open('names.txt', mode='r') as f:
list_of_names = f.readlines()
new_list_of_names = []
print(list_of_names)
for name in list_of_names:
name = name.strip('\n')
new_list_of_names.append(name)
print(new_list_of_names)
Or, for shorter code, use list comprehension:
with open('names.txt') as f:
list_of_names = f.readlines()
new_list_of_names = [name.strip('\n') for name in list_of_names]
print(list_of_names)
print(new_list_of_names)
(Note: mode='r' is redundant because the default mode is read.)

Read multiple files, search for string and store in a list

I am trying to search through a list of files, look for the words 'type' and the following word. then put them into a list with the file name. So for example this is what I am looking for.
File Name, Type
[1.txt, [a, b, c]]
[2.txt, [a,b]]
My current code returns a list for every type.
[1.txt, [a]]
[1.txt, [b]]
[1.txt, [c]]
[2.txt, [a]]
[2.txt, [b]]
Here is my code, i know my logic will return a single value into the list but I'm not sure how to edit it to it will just be the file name with a list of types.
output = []
for file_name in find_files(d):
with open(file_name, 'r') as f:
for line in f:
line = line.lower().strip()
match = re.findall('type ([a-z]+)', line)
if match:
output.append([file_name, match])
Learn to categorize your actions at the proper loop level.
In this case, you say that you want to accumulate all of the references into a single list, but then your code creates one output line per reference, rather than one per file. Change that focus:
with open(file_name, 'r') as f:
ref_list = []
for line in f:
line = line.lower().strip()
match = re.findall('type ([a-z]+)', line)
if match:
ref_list.append(match)
# Once you've been through the entire file,
# THEN you add a line for that file,
# with the entire reference list
output.append([file_name, ref_list])
You might find it useful to use a dict here instead
output = {}
for file_name in find_files(d):
with open(file_name, 'r') as f:
output[file_name] = []
for line in f:
line = line.lower().strip()
match = re.findall('type ([a-z]+)', line)
if match:
output[file_name].append(*match)

Naming lists based on the names of text files

I'm trying to write a function which takes word lists from text files and appends each word in the file to a list, with the same name as the text file. For instance, using the text files Verbs.txt and Nouns.txt would result in all the words in Verbs.txt being in a verbs list and all the nouns in a nounslist. I'm trying to do it in a for loop:
def loadAllWords():
fileList = ['Adjectives.txt', 'Adverbs.txt', 'Conjunctions.txt',
'IntransitiveVerbs.txt', 'Leadin.txt', 'Nounmarkers.txt',
'Nouns.txt', 'TransitiveVerbs.txt']
for file in fileList:
infile = open(file, 'r')
word_type = file[:-4]
word_list = [line for line in infile]
return word_list
Of course, I could do it easily once for each text file:
def loadAllWords():
infile = open("Adjectives.txt", "r")
wordList = []
wordList = [word for word in infile]
return wordList
but I'd like my function to do it automatically with each one. Is there a way to do this, or should I just stick with a for loop for each file?
You should use a dict for that like (untested):
results = {}
for file in file_list:
infile = open(file, 'r')
word_type = file[:-4]
results[word_type] = [line for line in infile]
return results
also you don't need the list comprehension, you can just do:
results[word_type] = list(infile)
You can create new variables with custom names by manipulating the locals() dictionary, which is where local variables are stored. But it is hard to imagine any case where this would be a good idea. I strongly recommend Stephen Roach’s suggestion of using a dictionary, which will let you keep track of the lists more neatly. But if you really want to create local variables for each file, you can use a slight variation on his code:
results = {}
for file in file_list:
with open(file, 'r') as infile:
word_type = file[:-4]
results[word_type] = list(infile)
# store each list in a local variable with that name
locals.update(results)

appending a single string to each element of a list in python

I'm trying to read a text file containing a list of user IDs and convert those IDs into email addresses by appending the #wherever.com ending to the IDs. Then I want to write those email addresses to a new file separated by commas.
textFile = open(“userID.txt”, “r”)
identList = textFile.read().split(“, “)
print identList
textFile.close()
emailString = “#wherever.com, ”
newList = [x + emailString for x in identList]
writeFile = open(“userEmail.txt”, “w”)
writeFile.writelines(newList)
writeFile.close()
I'm using python 3.x for Mac. This isn't working at all. I'm not sure if it is reading the initial file at all. It is certainly not writing to the new file. Can someone suggest where the program is failing to work?
Something like the following should work:
with open('userID.txt', 'r') as f_input, open('emails.txt', 'w') as f_output:
emails = ["{}#wherever.com".format(line.strip()) for line in f_input]
f_output.write(", ".join(emails))
So if you had a userID.txt file containing the following names, with one name per line:
fred
wilma
You would get a one line output file as follows:
fred#wherever.com, wilma#wherever.com
You could do it like this, also using context managers for reading and writing, because then you don't need to worry about closing the file:
identList = []
with open('userID.txt', 'r') as f:
identList = f.readlines().rstrip().split(',')
outString = ','.join([ '{0}#wherever.com'.format(x) for x in identList ])
with open('userEmail.txt', 'w') as f:
f.write(outString)
The conversion to string was done with join, which joins in this case the list elements formed in the comprehension with commas between them.

I need to open and rewrite a line in a file in Python [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Search and replace a line in a file in Python
How do I modify a text file in Python?
I have an input file that I need to rewrite with the different files needed to be modified before running a program. I have tried a variety of the solutions on here but none of them seem to work. I end up just overwriting my file with a blank file
f = open(filename, 'r+')
text = f.read()
text = re.sub('foobar', 'bar', text)
f.seek(0)
f.write(text)
f.truncate()
f.close()
Or with that code for instance the name I am changing is different each time I run the program so I need to replace the entire line not just one keyword
A simple way may be to read the text into a string, then concatenate the string with the text you want to write:
infile = open('hey.txt','r+')
content = infile.read()
text = ['foo','bar']
for item in text:
content +=item #adds 'foo' on first iteration, 'bar' on second
infile.write(content)
infile.close()
or to change a particular key word:
infile = open('hey.txt','r+')
content = infile.read()
table = str.maketrans('foo','bar')
content = content.translate(table) #replaces 'foo' with 'bar'
infile.write(content)
infile.close()
or to change by line, you can use readlines and refer to each line as the index of a list:
infile = open('hey.txt','r+')
content = infile.readlines() #reads line by line and out puts a list of each line
content[1] = 'This is a new line\n' #replaces content of the 2nd line (index 1)
infile.write(content)
infile.close()
Maybe not a particularly elegant way to solve the problem, but it could be wrapped up in a function and the 'text' variable could be a number of data types like a dictionary, list, etc. There are also a number of ways to replace each line in a file, it just depends on what the criteria are for changing the line (are you searching for a character or word in the line? Are you just looking to replace a line based on where it is in the file?)--so those are also some things to consider.
Edit: Added quotes to third code sample
Though ugly this solution ends up working
infile = open('file.txt', 'r+')
content = infile.readlines() #reads line by line and out puts a list of each line
content[1] = "foo \n" #replaces content of the 2nd line (index 1)
infile.close
infile = open('file.txt', 'w') #clears content of file.
infile.close
infile = open('file.txt', 'r+')
for item in content: #rewrites file content from list
infile.write("%s" % item)
infile.close()
Thanks for all the help!!

Categories

Resources