469,579 Members | 1,098 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,579 developers. It's quick & easy.

Testing for empty iterators?

In the old days, if I wanted to return a sequence of items, I'd return a
list, and loop over it like this:

for thing in getListOfThings ():
do something

With iterators, I'm doing:

for thing in getThingIterator ():
do something.

Now I need to test to see if the iterator is empty. Actually, it's a
unit test where I want to assert that it is empty. In the old days, I
would have done:

assertEquals (getListOfThings (), [])

but I don't see any clean way to do this with an iterator. The best I
can come up with is something like:

flag = False
for thing in getThingIterator ():
flag = True
break
assertEquals (flag, False)

Is that really the only way to do it?
Jul 18 '05 #1
7 10400
I wrote:
flag = False
for thing in getThingIterator ():
flag = True
break
assertEquals (flag, False)

Is that really the only way to do it?


Oh, never mind, I got it...

assertEquals (list (getThingIterator ()), [])
Jul 18 '05 #2
"Roy Smith" <ro*@panix.com> wrote in message
news:ro***********************@reader2.panix.com.. .
I wrote:
flag = False
for thing in getThingIterator ():
flag = True
break
assertEquals (flag, False)

Is that really the only way to do it?


Oh, never mind, I got it...

assertEquals (list (getThingIterator ()), [])


In general, I'd say your first approach was better, or something like:

try:
getThingIterator.next()
assert False, "getThingIterator pointed to non-empty iterable"
except StopIteration:
pass # no need to assert, by getting here, we know that getThingIterator
pointed to an empty iterable

Or if you'd prefer a more typical-looking assert:

expectedNullItem = null
try:
expectedNullItem = getThingIterator.next()
except StopIteration:
pass
assert expectedNullItem==null, "getThingIterator was supposed to be empty"
Suppose your iterator, through some bug in your code, pointed to a list of
100,000 database records, instead of an empty list as you expected. Making
a list from this iterator could be very time-consuming, when all you really
needed to know was that the iterator pointed to at least one element.

-- Paul
Jul 18 '05 #3
"Paul McGuire" <pt***@austin.stopthespam_rr.com> wrote:
Suppose your iterator, through some bug in your code, pointed to a list of
100,000 database records, instead of an empty list as you expected. Making
a list from this iterator could be very time-consuming, when all you really
needed to know was that the iterator pointed to at least one element.


I see your point, but this is a unit test. Even more so than normally,
in a unit test I think clarity of code is more important that
efficiency. And in this case, it's only inefficient if it fails the
test, which should never happen :-)
Jul 18 '05 #4
Roy Smith <ro*@panix.com> wrote in message news:<ro***********************@reader2.panix.com> ...
In the old days, if I wanted to return a sequence of items, I'd return a
list, and loop over it like this:

for thing in getListOfThings ():
do something

With iterators, I'm doing:

for thing in getThingIterator ():
do something.

Now I need to test to see if the iterator is empty. Actually, it's a
unit test where I want to assert that it is empty. In the old days, I
would have done:

assertEquals (getListOfThings (), [])

but I don't see any clean way to do this with an iterator. The best I
can come up with is something like:

flag = False
for thing in getThingIterator ():
flag = True
break
assertEquals (flag, False)

Is that really the only way to do it?


You may want to check this thread:

http://groups.google.it/groups?q=emp...gle.com&rnum=1

Michele Simionato
Jul 18 '05 #5
Roy Smith wrote:
Now I need to test to see if the iterator is empty. Actually, it's a
unit test where I want to assert that it is empty. In the old days, I
would have done:

assertEquals (getListOfThings (), [])

but I don't see any clean way to do this with an iterator. The best I
[and in a follow-up]
Oh, never mind, I got it...

assertEquals (list (getThingIterator ()), [])


An alternative would be

self.assertRaises(StopIteration, getThingIterator().next)

which is a bit stricter as it will choke if getThingIterator() returns a
list instead of an iterator.

Peter

Jul 18 '05 #6
Peter Otten <__*******@web.de> writes:
An alternative would be

self.assertRaises(StopIteration, getThingIterator().next)


Note that all those methods "consume" at least one element of the
iterator. You need something like ungetc for iterators (untested code):

class wrapper:
def __init__(self, iterator):
self.iterator = iterator
self.pushback = []
def __next__(self):
if self.pushback:
return self.pushback.pop(0)
def is_empty(self):
if self.pushback:
return False
try:
self.pushback.append(self.iterator.next())
return False
except StopIteration:
return True

Maybe something like that should go into itertools, if it's not
already there. Or the is_empty operation could be built into iterators.
Jul 18 '05 #7
Normally I add a __len__ method to my class
that contains an iterator if I need to keep
track of length/empty status. Basically it
is something like:

class getListOfThing:
def __init__(self):
self.ListOfThings=[]
self.next_index=0
#
# Code to build ListOfThings can be inserted here
# or in some other method.
#
return

def __iter__(self):
return self

def next(self):
#
# Try to get the next Thing
#
try: Thing=self.ListOfThings[self.next_index]
except IndexError:
self.next_index=0
raise StopIteration
#
# Increment the index pointer for the next call
#
self.next_index+=1
return Thing

def __len__(self):
return len(self.ListOfThings)
#
# Where ListOfThings is an attribute
# (list) that is defined in __init__
# and appended to in some way.
#

if __name__=="__main__":

T=getListOfThings()
print "Length of ListOfThings=",len(T)
for Thing in T:
# do something with Thing

But most of the time the fact that the iterator
doesn't return enything, so the loop is skipped
automatically is sufficient. I think you can do
this same thing with a yield, but this method works
and I continue to use it a lot.

HTH,
Larry Bates
Syscon, Inc.

"Roy Smith" <ro*@panix.com> wrote in message
news:ro***********************@reader2.panix.com.. .
In the old days, if I wanted to return a sequence of items, I'd return a
list, and loop over it like this:

for thing in getListOfThings ():
do something

With iterators, I'm doing:

for thing in getThingIterator ():
do something.

Now I need to test to see if the iterator is empty. Actually, it's a
unit test where I want to assert that it is empty. In the old days, I
would have done:

assertEquals (getListOfThings (), [])

but I don't see any clean way to do this with an iterator. The best I
can come up with is something like:

flag = False
for thing in getThingIterator ():
flag = True
break
assertEquals (flag, False)

Is that really the only way to do it?

Jul 18 '05 #8

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by steven | last post: by
10 posts views Thread by Brian Roberts | last post: by
25 posts views Thread by Matthias | last post: by
5 posts views Thread by gelbeiche | last post: by
2 posts views Thread by ma740988 | last post: by
24 posts views Thread by David | last post: by
7 posts views Thread by Moschops | last post: by
reply views Thread by suresh191 | last post: by
4 posts views Thread by guiromero | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.