How to read one character at a time from a file in Python?

Can someone tell me how can I do this?

+59
python file-io character
Jun 07 '10 at 9:11
source share
13 answers
with open(filename) as f: while True: c = f.read(1) if not c: print "End of file" break print "Read a character:", c 
+75
Jun 07 '10 at 9:19
source share

first open the file:

 with open("filename") as fileobj: for line in fileobj: for ch in line: print ch 
+32
Dec 25 '13 at 17:52
source share

I like the accepted answer: it is simple and will do the job. I would also suggest an alternative implementation:

 def chunks(filename, buffer_size=4096): """Reads `filename` in chunks of `buffer_size` bytes and yields each chunk until no more characters can be read; the last chunk will most likely have less than `buffer_size` bytes. :param str filename: Path to the file :param int buffer_size: Buffer size, in bytes (default is 4096) :return: Yields chunks of `buffer_size` size until exhausting the file :rtype: str """ with open(filename, "rb") as fp: chunk = fp.read(buffer_size) while chunk: yield chunk chunk = fp.read(buffer_size) def chars(filename, buffersize=4096): """Yields the contents of file `filename` character-by-character. Warning: will only work for encodings where one character is encoded as one byte. :param str filename: Path to the file :param int buffer_size: Buffer size for the underlying chunks, in bytes (default is 4096) :return: Yields the contents of `filename` character-by-character. :rtype: char """ for chunk in chunks(filename, buffersize): for char in chunk: yield char def main(buffersize, filenames): """Reads several files character by character and redirects their contents to `/dev/null`. """ for filename in filenames: with open("/dev/null", "wb") as fp: for char in chars(filename, buffersize): fp.write(char) if __name__ == "__main__": # Try reading several files varying the buffer size import sys buffersize = int(sys.argv[1]) filenames = sys.argv[2:] sys.exit(main(buffersize, filenames)) 

The code I suggest is essentially the same idea as your accepted answer: read the given number of bytes from the file. The difference is that it first reads a good piece of data (4006 is a good standard for X86, but you can try 1024 or 8192; any multiple size of your page), and then it gives the characters in that piece one.

The code I present may be faster for large files. Take for example . These are my temporary results (Mac Book Pro using OS X 10.7.4; so.py is the name I gave to the pasted code):

 $ time python so.py 1 2600.txt.utf-8 python so.py 1 2600.txt.utf-8 3.79s user 0.01s system 99% cpu 3.808 total $ time python so.py 4096 2600.txt.utf-8 python so.py 4096 2600.txt.utf-8 1.31s user 0.01s system 99% cpu 1.318 total 

Now: do not accept the buffer size of 4096 as universal truth; look at the results that I get for different sizes (buffer size (bytes) and time on the wall (sec)):

  2 2.726 4 1.948 8 1.693 16 1.534 32 1.525 64 1.398 128 1.432 256 1.377 512 1.347 1024 1.442 2048 1.316 4096 1.318 

As you can see, you can start earning a profit earlier (and my timings are most likely very inaccurate); buffer size is a trade-off between performance and memory. The default value of 4096 is a smart choice, but as always, measure first.

+14
Oct 06 '14 at 2:20
source share

Python itself can help you with this interactively:

 >>> help(file.read) Help on method_descriptor: read(...) read([size]) -> read at most size bytes, returned as a string. If the size argument is negative or omitted, read until EOF is reached. Notice that when in non-blocking mode, less data than what was requested may be returned, even if no size parameter was given. 
+8
Jun 07 '10 at 9:19
source share

Simply:

 myfile = open(filename) onecaracter = myfile.read(1) 
+5
Jun 07 2018-10-10T00:
source share

I learned a new idiom for this today, watching Raymond Hettinger Convert code to beautiful, idiomatic Python :

 import functools with open(filename) as f: f_read_ch = functools.partial(f.read, 1) for ch in iter(f_read_ch, ''): print 'Read a character:', repr(ch) 
+4
Feb 02 '14 at 4:28
source share

You should try f.read(1) , which is definitely the right thing and the right thing.

+2
Jun 07 '10 at 9:19
source share

Just read one character

 f.read(1) 
+2
Jun 07 '10 at 9:19
source share
 f = open('hi.txt', 'w') f.write('0123456789abcdef') f.close() f = open('hej.txt', 'r') f.seek(12) print f.read(1) # This will read just "c" 
0
Feb 25 '15 at
source share

This will also work:

 with open("filename") as fileObj: for line in fileObj: for ch in line: print(ch) 

It goes through every line in the file and every character in every line.

0
01 Dec '15 at 19:29
source share

To make an addition, if you are reading a file containing a huge vvvvery line that might break your memory, you might consider reading them into a buffer, and then giving each char

 def read_char(inputfile, buffersize=10240): with open(inputfile, 'r') as f: while True: buf = f.read(buffersize) if not buf: break for char in buf: yield char yield '' #handle the scene that the file is empty if __name__ == "__main__": for word in read_char('./very_large_file.txt'): process(char) 
0
Mar 11 '17 at 8:30
source share
 #reading out the file at once in a list and then printing one-by-one f=open('file.txt') for i in list(f.read()): print(i) 
0
Sep 10 '18 at 8:33
source share

Iron Man, Black Widow, Thanos die in the endgame.

-2
Apr 29 '19 at 11:20
source share



All Articles