How to save contents of a list to a file? - python

I have some question about my code:
def entry_book():
book = ["autor", "ime", "godina", "ISNB", "zanr", "cena", "broj"]
print ("Podaci za knjigu:")
book[0] = input ("Autor: ")
book[1] = input ("Naslov: ")
book[2] = input ("Godina: ")
book[3] = input ("ISNB: ")
book[4] = input ("Zanr: ")
book[5] = input ("Cena: ")
book[6] = input ("Kolicina: ")
record= "{}|{}|{}|{}|{}|{}|{}".format (book[0], book[1], book[2], book[3],
book[4], book[5], book[6])
print (book)
print (record)
f = open('books.txt','w')
f.write (record)
f.close()
f = open("books.txt")
x = f.read()
f.close()
print (x)
record1 = record.split('|')
print (record1)
second_meni()
This is code to store information on books, which I want to access later (like at a library). However, every time I add/create a new book, the old one gets deleted. Can anyone help me rewrite the code so it can store the old data as well. Or please explain what is the correct way to do it?

You have to use
f = open('knjige.txt', 'a')
'w' recreates the file (so use it only for NEW files, or if you don't mind it will be overwritten, 'a' appends to a file.
See python open built-in function: difference between modes a, a+, w, w+, and r+?
Also some unrelated suggestions:
Use the add instead of indices, or even better: use a dictionary
Use English variable names/comments.
Use code to check if the file read/write is ok, what if the file cannot be
written because of access restrictions or too less space on the disk?
Use different functions for the input, writing and printing, it makes testing/maintainability/extension much easier.

I took the liberty of pythonizing your code a bit.
def unos_knjiga():
headers = ["Autor", "Naslov", "Godina", "ISNB", "Zanr", "Cena", "Kolicina"]
print("Podaci za knjigu:")
knjiga = [input("{}".format(obj + ': ')) for obj in headers] # see 1
zapis = '|'.join(knjiga) # see 2
print(knjiga)
print(zapis)
with open('knjige.txt', 'a') as f: # see 3
f.write(zapis + '\n')
# i guess this is for testing?
with open("knjige.txt", 'r') as f:
x = f.read()
print(x)
# and this too?
zapis1 = zapis.split('|')
print(zapis1)
# this is not mentioned anywhere
second_meni()
1) This is a list comprehension. It creates lists by looping through stuff. In this case we are looping through the header list and use its items to construct input statements. The provided input is stored in the list.
2) .join() method. It does what you explicitly did. Joins items from iterators using a string between them.
3) the with keyword. Manages files so that you do not have to. Unless there is a reason not to use it, use it. This was also where the real problem with your code was. You have to use the 'a' mode. 'a' is for append, 'w' is for write. In this context, write means delete everything that was there and write this new stuff. Also note that 'a' mode can also create files, you do not need to temporarily switch to 'w' for that ('r' does not; 'r' is for read).
Cheers!

I think there are two methods to do this:
FIRST
f = open('knjige.txt','w')
is the piece of code which is responsible for rewriting the existing data in your file.
Other option which python offers to append some new data to the existing data is to open a file for writing using append 'a' method. So you can replace your above statement with
f = open('knjige.txt','a')
It won't replace the file with new data you enter.
SECOND
Other option is to open your file in read method, f = open('knjige.txt','r') and copy the existing data to a variable ( variable=f.read('knjige.txt') ). You can also use pickle module and its functions dump and load if you need to maintain your datatype.
Now concatenate your new data to the values in 'variable' and again open the file in write method and write it back to it.

Your call to open the file, f = open('knjige.txt','w') opens the file, truncating the existing contents should it exist. If you open the file with a mode that appends contents, like a it should not delete previous lines. See https://docs.python.org/2/library/functions.html#open for more information on opening files for reading / writing.

Related

Python: Exporting text list to a text file

I am new to Python and I was wondering how to save this hashed password list (stored in variable passwords)
['73868cb1848a216984dca1b6b0ee37bc', '2de9210e9173ca4151bb220a2ded6cdb', '8c064f4067cf0c59c68ec281f5786cb2']
to a text file in the format:
73868cb1848a216984dca1b6b0ee37bc
2de9210e9173ca4151bb220a2ded6cdb
8c064f4067cf0c59c68ec281f5786cb2
currently I am able to save it to a text file however it saves as
['73868cb1848a216984dca1b6b0ee37bc', '2de9210e9173ca4151bb220a2ded6cdb', '8c064f4067cf0c59c68ec281f5786cb2']
current code to save file:
f = open( 'hash.txt', 'w' )
f.write(repr(passwords) + '\n' )
f.close()
Please help :) Thank you
Reason for wanting to save in text is so I can call that list in a new script to decrypt them however because it saves as a list (and imports as a list) it creates a list in a list and messes up my decryption script.
Edit: Thank you all for the great answers :) its a huge help!
You can save it like this:
with open('hash.txt', 'w') as f:
f.write('\n'.join(passwords))
This achieves what you waht to do. (You could avoid the with-statement)
Load it like this:
passwords = []
with open('hash.txt', 'r') as f:
passwords.extend(f.read().split('\n'))
To use Python 3, you would have to be careful to convert the bytes to str first...
Greets.
EDIT:
Sorry, it must be passwords.extend() - not passwords.append().
You should use readlines() to pass the text from the file into the list and use that list like so:
passwords = []
with open('hash.txt', 'r') as f:
passwords = f.readlines()
f.close()
If you come across '\n', then just use something like "".join(passwords)
You can use the following code :
f = open( 'hash.txt', 'w' )
for a in passowrds:
f.write(a + '\n' ) #you have to pass them as separate variables
f.close()
Whenever you have to take out take out values from a list, you can use the for loop Example
list = ["cat","dog","lion"]
for animal in list:
print animal
This will print each animal in the list. You can use any other variable name in place of animal.
To open:
f = open('hash.txt', 'w')
To save:
f.write(file_path)

How do I save a list to file using python? [duplicate]

This question already has answers here:
Write and read a list from file
(3 answers)
Closed 8 years ago.
I was wondering how I can save a list entered by the user. I was wondering how to save that to a file. When I run the program it says that I have to use a string to write to it. So, is there a way to assign a list to a file, or even better every time the program is run it automatically updates the list on the file? That would be great the file would ideally be a .txt.
stuffToDo = "Stuff To Do.txt"
WRITE = "a"
dayToDaylist = []
show = input("would you like to view the list yes or no")
if show == "yes":
print(dayToDaylist)
add = input("would you like to add anything to the list yes or no")
if add == "yes":
amount=int(input("how much stuff would you like to add"))
for number in range (amount):
stuff=input("what item would you like to add 1 at a time")
dayToDaylist.append(stuff)
remove = input("would you like to remove anything to the list yes or no")
if add == "yes":
amountRemoved=int(input("how much stuff would you like to remove"))
for numberremoved in range (amountRemoved):
stuffremoved=input("what item would you like to add 1 at a time")
dayToDaylist.remove(stuffremoved);
print(dayToDaylist)
file = open(stuffToDo,mode = WRITE)
file.write(dayToDaylist)
file.close()
You can pickle the list:
import pickle
with open(my_file, 'wb') as f:
pickle.dump(dayToDaylist, f)
To load the list from the file:
with open(my_file, 'rb') as f:
dayToDaylist = pickle.load( f)
If you want to check if you have already pickled to file:
import pickle
import os
if os.path.isfile("my_file.txt"): # if file exists we have already pickled a list
with open("my_file.txt", 'rb') as f:
dayToDaylist = pickle.load(f)
else:
dayToDaylist = []
Then at the end of your code pickle the list for the first time or else update:
with open("my_file.txt", 'wb') as f:
pickle.dump(l, f)
If you want to see the contents of the list inside the file:
import ast
import os
if os.path.isfile("my_file.txt"):
with open("my_file.txt", 'r') as f:
dayToDaylist = ast.literal_eval(f.read())
print(dayToDaylist)
with open("my_file.txt", 'w') as f:
f.write(str(l))
for item in list:
file.write(item)
You should check out this post for more info:
Writing a list to a file with Python
Padraic's answer will work, and is a great general solution to the problem of storing the state of a Python object on disk, but in this specific case Pickle is a bit overkill, not to mention the fact that you might want this file to be human-readable.
In that case, you may want to dump it to disk like such (this is from memory, so there may be syntax errors):
with open("list.txt","wt") as file:
for thestring in mylist:
print(thestring, file=file)
This will give you a file with your strings each on a separate line, just like if you printed them to the screen.
The "with" statement just makes sure the file is closed appropriately when you're done with it. The file keyword param to print() just makes the print statement sort of "pretend" that the object you gave it is sys.stdout; this works with a variety of things, such as in this case file handles.
Now, if you want to read it back in, you might do something like this:
with open("list.txt","rt") as file:
#This grabs the entire file as a string
filestr=file.read()
mylist=filestr.split("\n")
That'll give you back your original list. str.split chops up the string it's being called on so that you get a list of sub-strings of the original, splitting it every time it sees the character you pass in as a parameter.

python clear content writing on same file

I am a newbie to python. I have a code in which I must write the contents again to my same file,but when I do it it clears my content.Please help to fix it.
How should I modify my code such that the contents will be written back on the same file?
My code:
import re
numbers = {}
with open('1.txt') as f,open('11.txt', 'w') as f1:
for line in f:
row = re.split(r'(\d+)', line.strip())
words = tuple(row[::2])
if words not in numbers:
numbers[words] = [int(n) for n in row[1::2]]
numbers[words] = [n+1 for n in numbers[words]]
row[1::2] = map(str, numbers[words])
indentation = (re.match(r"\s*", line).group())
print (indentation + ''.join(row))
f1.write(indentation + ''.join(row) + '\n')
In general, it's a bad idea to write over a file you're still processing (or change a data structure over which you are iterating). It can be done...but it requires much care, and there is little safety or restart-ability should something go wrong in the middle (an error, a power failure, etc.)
A better approach is to write a clean new file, then rename it to the old name. For example:
import re
import os
filename = '1.txt'
tempname = "temp{0}_{1}".format(os.getpid(), filename)
numbers = {}
with open(filename) as f, open(tempname, 'w') as f1:
# ... file processing as before
os.rename(tempname, filename)
Here I've dropped filenames (both original and temporary) into variables, so they can be easily referred to multiple times or changed. This also prepares for the moment when you hoist this code into a function (as part of a larger program), as opposed to making it the main line of your program.
You don't strictly need the temporary name to embed the process id, but it's a standard way of making sure the temp file is uniquely named (temp32939_1.txt vs temp_1.txt or tempfile.txt, say).
It may also be helpful to create backups of the files as they were before processing. In which case, before the os.rename(tempname, filename) you can drop in code to move the original data to a safer location or a backup name. E.g.:
backupname = filename + ".bak"
os.rename(filename, backupname)
os.rename(tempname, filename)
While beyond the scope of this question, if you used a read-process-overwrite strategy frequently, it would be possible to create a separate module that abstracted these file-handling details away from your processing code. Here is an example.
Use
open('11.txt', 'a')
To append to the file instead of w for writing (a new or overwriting a file).
If you want to read and modify file in one time use "r+' mode.
f=file('/path/to/file.txt', 'r+')
content=f.read()
content=content.replace('oldstring', 'newstring') #for example change some substring in whole file
f.seek(0) #move to beginning of file
f.write(content)
f.truncate() #clear file conent "tail" on disk if new content shorter then old
f.close()

Saving an Element in an Array Permanently

I am wondering if it is possible to do what is explained in the title in Python. Let me explain myself better. Say you have an array:
list = []
You then have a function that takes a user's input as a string and appends it to the array:
def appendStr(list):
str = raw_input("Type in a string.")
list.append(str)
I would like to know if it's possible to save the changes the user made in the list even after the program has closed. So if the user closed the program, opened it again, and printed the list the strings he/she added would appear. Thank you for your time. This may be a duplicate question and if so I'm sorry, but I couldn't find another question like this for Python.
A simpler solution will be to use json
import json
li = []
def getinput(li):
li.append(raw_input("Type in a string: "))
To save the list you would do the following
savefile = file("backup.json", "w")
savefile.write(json.dumps(li))
And to load the file you simply do
savefile = open("backup.json")
li = json.loads(savefile.read())
You may want to handle the case where the file does not exist. One thing to note would be that complex structures like classes cannot be stored as json.
You will have to save it into a file:
Writing to a file
with open('output.txt', 'w') as f:
for item in lst: #note: don't call your variable list as that is a python reserved keyword
f.write(str(item)+'\n')
Reading from a file (at the start of the program)
with open('output.txt') as f:
lst = f.read().split('\n')
If a string, writing in a file as suggested is a good way to go.
But if the element is not a string, "pickling" might be the keyword you are looking for.
Documentation is here:
https://docs.python.org/2/library/pickle.html
It seems to me this post answer your question:
Saving and loading multiple objects in pickle file?

Python: Writing to a file and reading it back out

I am saving a dictionary of student names as keys and grades lists as values. I am attempting to write the values to a file. At the moment I am writing them as strings.
def save_records(students, filename):
#saves student records to a file
out_file = open(filename, "w")
for x in students.keys():
out_file.write(x + " " + str(students[x]) + "\n")
out_file.close()
After saving the file, I try to read it back. The pertinent part of the read out is below.
while True:
in_line = in_file.readline()
if not in_line:
break
#deletes line read in
in_line = in_line[:-1]
#initialize grades list
in_line = in_line.split()
name = in_line[0]
students[name] = map(int, in_line[1:])
The read out code works well for normal text files that are pre-formatted. The format of the textfile is: key (whitespace) values separated by whitespace "\n". I would like to know how to write in to a text file by combining string and list elements.
If you have control over writing the data, I would recommend using a well-established format, such as JSON or INI. This would allow you to make use of common libraries, such as the json or ConfigParser modules, respectively.
Would it not be easier to use something like pythons pickle which is for storing things like dicts
...and then pretty print output to a separate file?
It's hard to say without knowing how you plan on using this...
Since students[name] = map(int, in_line[1:]), i assume you want to print the items of the list student[x] with whitespaces inbetween.
You could use the str.join method
' '.join(map(str,students[x]))
You may want to consider using Comma Separated Value files (aka csv files) instead of plain text files, as these provide a more structured way to read and write your data. Once written, you can open them in a spreadsheet program like Excel to view and edit their contents.
Re-writing your functions to work with csv files, and assuming you are using Python 2.x, we get something like:
import csv
def save_records(students, filename):
# note that csv files are binary so on Windows you
# must write in 'wb' mode; also note the use of `with`
# which ensures the file is closed once the block is
# exited.
with open(filename, 'wb') as f:
# create a csv.writer object
csv_out = csv.writer(f)
for name, grades in students.iteritems():
# write a single data row to the file
csv_out.writerow([name]+grades)
def read_records(filename):
students = dict()
# note that we must use 'rb' to read in binary mode
with open(filename, 'rb') as f:
# create a csv.reader object
csv_in = csv.reader(f)
for line in csv_in:
# name will have type `str`
name = line[0]
grades = [int(x) for x in line[1:]]
# update the `students` dictionary
students[name] = grades
return students

Categories

Resources