Assignment in a while?

N

none

Hi all,

First, let me preface this by the fact that I'm completely new to the
language, but not to programming in general.

I'm trying to get my feet wet with something near and dear to my heart:
database programming. Here's what I've got:

import pgdb;

dbh = pgdb.connect(database = 'test')
sth = dbh.cursor()
sth.execute("SELECT * FROM capitals")
#while 1:
#results = sth.fetchone()
#if results == None:
#break
#print results
while results = sth.fetchone():
print results

If I try to run the above code, I get a SyntaxError indicating that I
can't do an assignment in the while loop. I found a way around this
(see the commented out while loop), but it seems hackish. Assignment
within a while loop seems like a pretty standard thing, so I'm just
curious what I'm missing.

Thanks in advance,
Ben
 
N

none

So it seems that I stumbled on the idiomatic way of doing this then.
Well, as they say, "When in Rome..." :). Thanks for pointing out the
FAQ. I'll be reading up on it.

Cheers,
Ben
 
B

bill pursell

none said:
import pgdb;

dbh = pgdb.connect(database = 'test')
sth = dbh.cursor()
sth.execute("SELECT * FROM capitals")
#while 1:
#results = sth.fetchone()
#if results == None:
#break
#print results
while results = sth.fetchone():
print results

If I try to run the above code, I get a SyntaxError indicating that I
can't do an assignment in the while loop. I found a way around this
(see the commented out while loop), but it seems hackish. Assignment
within a while loop seems like a pretty standard thing, so I'm just
curious what I'm missing.

A more pythonic way to do that is something like:

for results in sth.fetchall():
print results

(I'm not familiar with pgdb, but if it's a reasonable module it will
have some function that returns an iterator.)

In the beginning of my python experience, I was a bit irritated at
being unable to assign and check a condition in one statement, but the
irritation really doesn't last very long. Python has a huge amount of
inherent beauty, and is well worth the time.
 
A

Ant

There are various ways you could do this:

If the number of results won't be too big:

....
for result in sth.fetchall():
print result

If it may be very large:
....

result = sth.fetchone()
while result:
print result
result = sth.fetchone()

Or perhaps nicer:

....
def result_iterator(result_set):
yield result_set.fetchone()

for result in result_iterator(sth):
print result

HTH.
 
D

Duncan Booth

none said:
If I try to run the above code, I get a SyntaxError indicating that I
can't do an assignment in the while loop. I found a way around this
(see the commented out while loop), but it seems hackish. Assignment
within a while loop seems like a pretty standard thing, so I'm just
curious what I'm missing.

Not much, you cannot assign to a variable in the controlling expression
of a while loop. However, for loops do assign values to variables, so if
the form with the break offends you, try restructuring your code as a for
loop. For example:

for results in iter(sth.fetchone, None):
print results

or in many cases you can just fetch everything in one go:

for results in sth.fetchall():
print results
 
F

Fredrik Lundh

none said:
So it seems that I stumbled on the idiomatic way of doing this then.
Well, as they say, "When in Rome..." :). Thanks for pointing out the
FAQ. I'll be reading up on it.

the idiomatic way to loop in Python is to use iterators/generators. if
you have a callable that fetches data from some resource and returns
a "sentinel" when you get to the end, you can use the iter function to
turn it into an iterator:
Help on built-in function iter in module __builtin__:

iter(...)
iter(collection) -> iterator
iter(callable, sentinel) -> iterator

Get an iterator from an object. In the first form, the argument must
supply its own iterator, or be a sequence.
In the second form, the callable is called until it returns the sentinel.

given this, your loop can be written:

for result in iter(std.fetchone, None):
print result

</F>
 
B

Ben Thul

The inline iterator version fits very well with my sensibilities. The
problem that I have with fetchall is that sometimes you need to deal
with a very large dataset. Calling fetchall() on it will put the whole
thing in memory, which is no good. Better to iterate over it one row at
a time, IMO.

Thanks a ton!
Ben
 
A

Alex Martelli

none said:
can't do an assignment in the while loop. I found a way around this
(see the commented out while loop), but it seems hackish. Assignment
within a while loop seems like a pretty standard thing, so I'm just
curious what I'm missing.

I see you've already received many excellent suggestions, and just
wanted to point out the way in which you CAN "assign-and-test" in those
rare occasions where you really want to (in my experience, that boils
down to: I need Python code whose structure is as close as possible to
some other's language -- either because I need to transliterate into
Python some published "reference implementation" kind of algorithm, or
because I know I'm just doing a _prototype_ in Python, and once that's
accepted some poor folks will have to transliterate it into C or
whatever). Anyway, it boils down to something like...:

class ValueHolder(object):
def __init__(self, value=None):
self.set(value)
def set(self, value):
self.value = value
return value
data = ValueHolder()

and then, say, something like...:

while data.set(zip.zop()):
frobnicate(data.value)

Not as Pythonic as iterators etc, but structurally very close to

while (xx=zip.zop()) {
frobnicate(xx);
}

if that's what you need to stick close to!-)


Alex
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,431
Messages
2,571,678
Members
48,796
Latest member
Greg L.

Latest Threads

Top