473,569 Members | 2,691 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

while c = f.read(1)

I have a Python snippet:

f = open("blah.txt" , "r")
while True:
c = f.read(1)
if c == '': break # EOF
# ... work on c

Is some way to make this code more compact and simple? It's a bit
spaghetti.

This is what I would ideally like:

f = open("blah.txt" , "r")
while c = f.read(1):
# ... work on c

But I get a syntax error.

while c = f.read(1):
^
SyntaxError: invalid syntax

And read() doesn't work that way anyway because it returns '' on EOF
and '' != False. If I try:

f = open("blah.txt" , "r")
while (c = f.read(1)) != '':
# ... work on c

I get a syntax error also. :(

Is this related to Python's expression vs. statement syntactic
separation? How can I be write this code more nicely?

Thanks

Aug 19 '05 #1
75 5299
On 18 Aug 2005 22:21:53 -0700, "Greg McIntyre" <gr**@puyo.cjb. net> wrote:
I have a Python snippet:

f = open("blah.txt" , "r")
while True:
c = f.read(1)
if c == '': break # EOF
# ... work on c

Is some way to make this code more compact and simple? It's a bit
spaghetti.

This is what I would ideally like:

f = open("blah.txt" , "r")
while c = f.read(1):
# ... work on c
How about (untested):

for c in iter((lambda f=open('blah.tx t', 'r'): f.read(1)), ''):
# ... work on c

("if c=='': break" functionality courtesy of iter(f, sentinel) form above)

Of course, reading characters one by one is not very efficient, so if the file
is reasonably sized, you might just want to read the whole thing and iterate
through it, something like

for c in open('blah.txt' ).read():
# ... work on c
But I get a syntax error.

while c = f.read(1):
^
SyntaxError: invalid syntax

And read() doesn't work that way anyway because it returns '' on EOF
and '' != False. If I try:

f = open("blah.txt" , "r")
while (c = f.read(1)) != '':
# ... work on c

I get a syntax error also. :(

Is this related to Python's expression vs. statement syntactic
separation? How can I be write this code more nicely?

Yes, it is related as you suspect. I'll leave it to you to make
a chunk-buffering one-liner for huge files that iterates by characters,
if one-liners turn you on. Otherwise it is easy to write a generator that will do it.
Byt the time I post this, someone will probably have done it ;-)
Regards,
Bengt Richter
Aug 19 '05 #2
Greg McIntyre wrote:
I have a Python snippet:

f = open("blah.txt" , "r")
while True:
c = f.read(1)
if c == '': break # EOF
# ... work on c

Is some way to make this code more compact and simple? It's a bit
spaghetti.


That's not spaghetti. Not even close.

In any case, is there a reason you are reading one character at a time
instead of reading the contents of the file into memory and iterating
over the resulting string?

f = open('blah.txt' , 'r')
text = f.read()
f.close()

for c in f:
# ...

If you must read one character at a time,

def reader(fileobj, blocksize=1):
"""Return an iterator that reads blocks of a given size from a
file object until EOF.
"""
# Note that iter() can take a function to call repeatedly until it
# receives a given sentinel value, here ''.
return iter(lambda: fileobj.read(bl ocksize), '')

f = open('blah.txt' , 'r')
try:
for c in reader(f):
# ...
finally:
f.close()

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Aug 19 '05 #3
Quoth "Greg McIntyre" <gr**@puyo.cjb. net>:
| I have a Python snippet:
|
| f = open("blah.txt" , "r")
| while True:
| c = f.read(1)
| if c == '': break # EOF
| # ... work on c
|
| Is some way to make this code more compact and simple? It's a bit
| spaghetti.

Actually I'd make it a little less compact -- put the "break"
on its own line -- but in any case this is fine. It's a natural
and ordinary way to express this in Python.

....
| But I get a syntax error.
|
| while c = f.read(1):
| ^
| SyntaxError: invalid syntax
|
| And read() doesn't work that way anyway because it returns '' on EOF
| and '' != False. If I try:

This is the part I really wanted to respond to. Python managed
without a False for years (and of course without a True), and if
the introduction of this superfluous boolean type really has led
to much of this kind of confusion, then it was a bad idea for sure.

The condition that we're looking at here, and this is often the
way to look at conditional expressions in Python, is basically
something vs. nothing. In this and most IO reads, the return
value will be something, until at end of file it's nothing.
Any type of nothing -- '', {}, [], 0, None - will test "false",
and everything else is "true". Of course True is true too, and
False is false, but as far as I know they're never really needed.

You are no doubt wondering when I'm going to get to the part where
you can exploit this to save you those 3 lines of code. Sorry,
it won't help with that.

| Is this related to Python's expression vs. statement syntactic
| separation? How can I be write this code more nicely?

Yes, exactly. Don't worry, it's nice as can be. If this is
the worst problem in your code, you're far better off than most
of us.

Donn Cave, do**@drizzle.co m
Aug 19 '05 #4
Greg McIntyre wrote:
I have a Python snippet:

f = open("blah.txt" , "r")
while True:
c = f.read(1)
if c == '': break # EOF
That could read like this
if not c: break # EOF
# see below for comments on what is true/false
# ... work on c

Is some way to make this code more compact and simple? It's a bit
spaghetti.
Not at all, IMHO. This is a simple forward-branching exit from a loop in
explicable circumstances (EOF). It is a common-enough idiom that doesn't
detract from readability & understandabili ty. Spaghetti is like a GOTO
that jumps backwards into the middle of a loop for no discernable reason.

This is what I would ideally like:

f = open("blah.txt" , "r")
while c = f.read(1):
# ... work on c

But I get a syntax error.

while c = f.read(1):
^
SyntaxError: invalid syntax

And read() doesn't work that way anyway because it returns '' on EOF
and '' != False. >
You have a bit of a misunderstandin g here that needs correcting:

In "if <blah>" and "while <blah>", <blah> is NOT restricted to being in
(True, False). See section 5.10 of the Python Reference Manual:

"""
In the context of Boolean operations, and also when expressions are used
by control flow statements, the following values are interpreted as
false: None, numeric zero of all types, empty sequences (strings, tuples
and lists), and empty mappings (dictionaries). All other values are
interpreted as true.
"""

.... AND it's about time that list is updated to include False explicitly
-- save nitpicking arguments about whether False is covered by
"numeric zero of all types" :-)
If I try:

f = open("blah.txt" , "r")
while (c = f.read(1)) != '':
# ... work on c

I get a syntax error also. :(

Is this related to Python's expression vs. statement syntactic
separation? How can I be write this code more nicely?

Thanks


How about
for c in f.read():
?
Note that this reads the whole file into memory (changing \r\n to \n on
Windows) ... performance-wise for large files you've spent some memory
but clawed back the rather large CPU time spent doing f.read(1) once per
character. The "more nicely" factor improves outasight, IMHO.

Mild curiosity: what are you doing processing one character at a time
that can't be done with a built-in function, a standard module, or a
3rd-party module?
Aug 19 '05 #5
Bengt Richter wrote:
On 18 Aug 2005 22:21:53 -0700, "Greg McIntyre" <gr**@puyo.cjb. net> wrote:

I have a Python snippet:

f = open("blah.txt" , "r")
while True:
c = f.read(1)
if c == '': break # EOF
# ... work on c

Is some way to make this code more compact and simple? It's a bit
spaghetti.

This is what I would ideally like:

f = open("blah.txt" , "r")
while c = f.read(1):
# ... work on c


How about (untested):

for c in iter((lambda f=open('blah.tx t', 'r'): f.read(1)), ''):
# ... work on c

:-)
Bengt, did you read on to the bit where the OP wanted to do it "more
nicely"? YMMV, but I think you've strayed into "pas devant les enfants"
territory.
(-:

Cheers,
John
Aug 19 '05 #6
On 18 Aug 2005 22:21:53 -0700
Greg McIntyre wrote:
I have a Python snippet:

f = open("blah.txt" , "r")
while True:
c = f.read(1)
if c == '': break # EOF
# ... work on c

Is some way to make this code more compact and simple? It's a bit
spaghetti.


import itertools
f = open("blah.txt" , "r")
for c in itertools.chain (*f):
print c
# ...

The "f" is iterable itself, yielding a new line from the file every time.
Lines are iterable as well, so the itertools.chain iterates through each
line and yields a character.

--
jk
Aug 19 '05 #7
<en**********@o spaz.ru> writes:
import itertools
f = open("blah.txt" , "r")
for c in itertools.chain (*f):
print c
# ...

The "f" is iterable itself, yielding a new line from the file every time.
Lines are iterable as well, so the itertools.chain iterates through each
line and yields a character.


But that can burn an unlimited amount of memory if there are long
stretches of the file with no newlines. There's no real good way
around ugly code.
Aug 19 '05 #8
en**********@os paz.ru wrote:
import itertools
f = open("blah.txt" , "r")
for c in itertools.chain (*f):
print c
# ...

The "f" is iterable itself, yielding a new line from the file every time.
Lines are iterable as well, so the itertools.chain iterates through each
line and yields a character.


As far as I can tell, that code is just going to read the whole file in
when Python does the *arg expansion. What's the point?

--
Robert Kern
rk***@ucsd.edu

"In the fields of hell where the grass grows high
Are the graves of dreams allowed to die."
-- Richard Harter

Aug 19 '05 #9
On 19 Aug 2005 03:43:31 -0700
Paul Rubin wrote:
<en**********@o spaz.ru> writes:
import itertools
f = open("blah.txt" , "r")
for c in itertools.chain (*f):


But that can burn an unlimited amount of memory if there are long
stretches of the file with no newlines. There's no real good way
around ugly code.


I agree. Moreover, in fact, it is the same as just

for c in f.read():
# ...

--
jk
Aug 19 '05 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
5632
by: Carlo Filippini | last post by:
Hi I try to measure how fast an ftp download is going on the fly. I do something like: $|=1; my $count =0; open (CMD, "ftp.script 2>&1 |") or die "Can't execute: $!"; while (<CMD>){ print "Result: $_ \n"; if ($_ =~ /\#/) {
0
2656
by: sstark | last post by:
Hi, I have a web/cgi script that allows users to upload a file to the web server. I want to only allow files up to a certain size, which is stored in $imageFileMaxSize (typically 75K). That part works correctly, i.e. the script does not allow uploads larger than $imageFileMaxSize. The problem is, when a user attempts to upload a file larger...
2
8982
by: Gunnar | last post by:
Hello, I've just written a CPP program that reads integers from a binary file, and used this code while (my_ifstram.read( (char* ) &number, sizeof(int)) { // do something with number } My question is now, where can I find a manual that describes what the read method does with the ifstream object? I'm sitting here with my Linux/Debian...
18
4866
by: jas | last post by:
Hi, I would like to start a new process and be able to read/write from/to it. I have tried things like... import subprocess as sp p = sp.Popen("cmd.exe", stdout=sp.PIPE) p.stdin.write("hostname\n") however, it doesn't seem to work. I think the cmd.exe is catching it.
4
2473
by: yo_mismo | last post by:
Hi everyone, I'm trying to read the first line of a file this way: .... .... .... .... new_line=0; while((read=read(fd, &info, sizeof(info))) > 0 && !new_line){ if (strcmp(&info, "\n") != 0){
4
3837
by: Ollie Cook | last post by:
Hi, I am having some difficulty with read(2) and interrupting signals. I expect I am misunderstanding how the two work together, so would appreciate some guidance. I am trying to 'time out' a socket read after a certain delay. The logic is (I will provide a test program below): - create and connect socket
4
12349
by: Dave | last post by:
I'm using a datareader to get data from an sql table. The line that gives the error is as follow, dtrReceivers.ToString() which gives the error, Invalid attempt to read when no data is present which is correct. The line works when data is in the row. But shouldn't the
2
3682
by: Tiger | last post by:
I try to write a struct into a brut file but I can't write all var in this struct when I try to add user I have that : > testmachine:/usr/share/my_passwd# ./my_passwd -a users.db > Ajout d'une entrée dans la base : > > Username : test > Password : aze > Gecos : qsd
2
2116
by: Saran | last post by:
Hi, Below is my scenario... I want to restrict my clients to access one of my class property in ReadOnly mode. At the same time as an author of the component i would like to have read-write access on it. I tried to write 'Public ReadOnly' and 'Private WriteOnly', but didn't work.
1
2442
by: DannyMc | last post by:
Hi all, I am in the progress of consolidating my 2 NIS databases into 1. My first step is to get the NIS record for particular department. I have software.csv which contain list of name in. software.csv: John Travolta Elthon John Sean King Ston Taylor Swif t Nicole cage
0
7698
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main...
0
7612
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7924
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
8122
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
0
7970
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6284
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
0
3640
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2113
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
1
1213
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.