473,785 Members | 2,261 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Question about exausted iterators

Is there a good reason why when you try to take an element from an
already exausted iterator, it throws StopIteration instead of some other
exception ? I've lost quite some times already because I was using a lot
of iterators and I forgot that that specific function parameter was one.

Exemple :
def f(i): .... print list(i)
.... print list(i)
.... f(iter(range(2) )) [0, 1]
[]


This is using Python 2.4.2
May 17 '06 #1
21 1412

"Christophe " <ch************ *@free.fr> wrote in message
news:44******** **************@ news.free.fr...
Is there a good reason why when you try to take an element from an
already exausted iterator, it throws StopIteration instead of some other
exception ?
Yes.
..
..
To distinguish the control message "I am done yielding values, as per the
code specification (so don't bother calling me again)." from error messages
that say "Something is wrong, I cannot yield values and give up." In other
words, to distinguish expected correct behavior from unexpected incorrect
behavior. This is essential for the normal and correct use of iterators.
I've lost quite some times already because I was using a lot
of iterators and I forgot that that specific function parameter was one.
I think you mean 'specific function argument' for a parameter which could
be any iterable.
Exemple :

Example
def f(i): ... print list(i)
... print list(i)
... f(iter(range(2) ))

[0, 1]
[]


As per specification.
I am guessing that you want the first list() call to terminate normally and
return a list, which requires exhausted i to raise StopIteration, while you
want the second list() to not terminate but raise an exception, which
requires exhausted i to raise something other than StopIteration. Tough.

One solution is call list(i) exactly once:

def f(i):
li = list(i)
print li
print li

Another is to document f as requiring that i be a non-iterator reiterable
iterable and only pass correct arguments.

A third is to add a line like
if iter(i) is i: raise TypeError("inpu t appears to be iterator")

This is not quite exact since it will improperly exclude self-iterator
reiterables (which, I believe, no builtin is) and improperly pass
non-reiterable non-iterator iterables (at least some file objects). But it
might work for all your cases.

Terry Jan Reedy

May 17 '06 #2
Christophe wrote:
Is there a good reason why when you try to take an element from an
already exausted iterator, it throws StopIteration instead of some other
exception ? I've lost quite some times already because I was using a lot
of iterators and I forgot that that specific function parameter was one.

Exemple :
>>> def f(i): ... print list(i)
... print list(i)
... >>> f(iter(range(2) ))

[0, 1]
[]


Whether trying to iterate over an exhausted iterator should be treated
differently is appication dependent. In most cases, you don't really
care to distinguish between an iterator that yields no elements and an
iterator that did yield some elements before but it has been exhausted.
If you do care, you can roll your own iterator wrapper:
class ExhaustibleIter ator(object):
def __init__(self, iterable):
self._next = getattr(iterabl e, 'next', iter(iterable). next)
self._exhausted = False

def next(self):
if self._exhausted :
raise ExhaustedIterat orException()
try: return self._next()
except StopIteration:
self._exhausted = True
raise

def __iter__(self):
return self

class ExhaustedIterat orException(Exc eption):
pass
And then in your function:
def f(i):
i = ExhaustibleIter ator(i)
print list(i)
print list(i)
HTH,
George

May 17 '06 #3
Terry Reedy a écrit :
"Christophe " <ch************ *@free.fr> wrote in message
news:44******** **************@ news.free.fr...
Is there a good reason why when you try to take an element from an
already exausted iterator, it throws StopIteration instead of some other
exception ?

Yes.
.
.
To distinguish the control message "I am done yielding values, as per the
code specification (so don't bother calling me again)." from error messages
that say "Something is wrong, I cannot yield values and give up." In other
words, to distinguish expected correct behavior from unexpected incorrect
behavior. This is essential for the normal and correct use of iterators.


You talk about expected behaviour and my expected behaviour is that an
iterator should not be usable once it has raised StopIteration once.
>def f(i):


... print list(i)
... print list(i)
...
>f(iter(ran ge(2)))


[0, 1]
[]

As per specification.


Specifications sometimes have "bugs" too.
I am guessing that you want the first list() call to terminate normally and
return a list, which requires exhausted i to raise StopIteration, while you
want the second list() to not terminate but raise an exception, which
requires exhausted i to raise something other than StopIteration. Tough.
Exactly. This would be a sane way to handle it.
One solution is call list(i) exactly once:

def f(i):
li = list(i)
print li
print li


Ok, call me stupid if you want but I know perfectly well the "solution"
to that problem ! Come on, I was showing example code of an horrible
gotcha on using iterators.

Instead of saying that all works as intended could you be a little
helpful and tell me why it was intended in such an obviously broken way
instead ?
May 18 '06 #4

Christophe wrote:
Ok, call me stupid if you want but I know perfectly well the "solution"
to that problem ! Come on, I was showing example code of an horrible
gotcha on using iterators.

OK, your are stupid ;-)
Why asking questions when you don't want to listen answers ?



Instead of saying that all works as intended could you be a little
helpful and tell me why it was intended in such an obviously broken way
instead ?


Why an exausted iterator must return an Exception (other than
StopIteration of course) ?
Well an exausted iterator could be seen like an empty string or an
empty list (or tons of others things), so you expect the code
for car in "":
print car
to return an Exception because it's empty ???
It's your job to check the iterator when it need to be.

Regards.
Dom

May 18 '06 #5
looping a écrit :
Christophe wrote:
Ok, call me stupid if you want but I know perfectly well the "solution"
to that problem ! Come on, I was showing example code of an horrible
gotcha on using iterators.
OK, your are stupid ;-)
Why asking questions when you don't want to listen answers ?


Because I'm still waiting for a valid answer to my question. The answer
"Because it has been coded like that" or is not a valid one.
Instead of saying that all works as intended could you be a little
helpful and tell me why it was intended in such an obviously broken way
instead ?


Why an exausted iterator must return an Exception (other than
StopIteration of course) ?


Because it's exausted. Because it has been for me a frequent cause of
bugs and because I have yet to see a valid use case for such behaviour.
Well an exausted iterator could be seen like an empty string or an
empty list (or tons of others things), so you expect the code
for car in "":
print car
to return an Exception because it's empty ???
Of course not.
It's your job to check the iterator when it need to be.


It's my job to avoid coding bugs, it's the language job to avoid placing
pitfalls everywhere I go.

I must confess I have a strong opinion on that point. Not long ago I
started working on some fresh code where I decided to use a lot of
iterators and set instead of list if possible. That behaviour has caused
me to lose quite some time tracking bugs.
May 18 '06 #6
Christophe wrote:
Because I'm still waiting for a valid answer to my question. The answer
"Because it has been coded like that" or is not a valid one.


it's been coded like that because that's what the specification says:

http://www.python.org/dev/peps/pep-0234/

</F>

May 18 '06 #7
Fredrik Lundh a écrit :
Christophe wrote:
Because I'm still waiting for a valid answer to my question. The
answer "Because it has been coded like that" or is not a valid one.

it's been coded like that because that's what the specification says:

http://www.python.org/dev/peps/pep-0234/


I didn't though I had to mention that "Because the spec has been writen
like that" wasn't a valid answer either.
May 18 '06 #8
Christophe wrote:
Because I'm still waiting for a valid answer to my question. The
answer "Because it has been coded like that" or is not a valid one.


it's been coded like that because that's what the specification says:

http://www.python.org/dev/peps/pep-0234/


I didn't though I had to mention that "Because the spec has been writen
like that" wasn't a valid answer either.


so what is a valid answer?

</F>

May 18 '06 #9
Christophe wrote:
Fredrik Lundh a écrit :
Christophe wrote:
Because I'm still waiting for a valid answer to my question. The
answer "Because it has been coded like that" or is not a valid one.

it's been coded like that because that's what the specification says:

http://www.python.org/dev/peps/pep-0234/


I didn't though I had to mention that "Because the spec has been writen
like that" wasn't a valid answer either.


The important thing is: it _is_ specified. And what about code like this:
iterable = produce_some_it erable()

for item in iterable:
if some_condition( item)
break
do_something()

for item in iterable:
do_something_wi th_the_rest()
If it weren't for StopIteration raised if the iterable was exhausted, you'd
have to clutter that code with something like

try:
for item in iterable:
do_something_wi th_the_rest()
except IteratorExhaust ed:
pass

What makes you say that this is better than the above? Just because _you_
had some cornercases that others seems not to have (at least that
frequently, I personally can't remember I've ever bitten by it) isn't a
valid reason to _not_ do it as python does.

Besides that: it would be a major change of semantics of iterators that I
seriously doubt it would make it into anything before P3K. So - somewhat a
moot point to discuss here I'd say.

Diez
May 18 '06 #10

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

Similar topics

1
4198
by: Ray Gardener | last post by:
I was wondering if anyone had tried implementing fuzzy logic set concepts in C++, because in FL, the concept of "type" or "class" is fuzzy; things belong (or are of) a given type only by degree. e.g., in a hypothetical fuzzy C++ language one could say: class pickle : public vegetable 0.2 { // pickle is not so much a vegetable as, say, onion is. };
3
1235
by: deancoo | last post by:
If I have a container, say a vector, with 5 elements, and I initialize iterator variables to point to the beginning and end of the container, are those iterators going to always be valid if I replace the elements of the container? The size stays the same. It seems to be working now, but I thought I read somewhere something about this not always working out. Any thoughts? d
1
3058
by: Dave Townsend | last post by:
Hi, Can anybody help me with the following piece of code? The purpose behind the code is to parse HTML files, strip out the tags and return the text between tags. This is part of a larger application which will perform "searches" for text values in a directory of html files, trying to match only the non-tagged text in the documents.
24
3968
by: Lasse Vågsæther Karlsen | last post by:
I need to merge several sources of values into one stream of values. All of the sources are sorted already and I need to retrieve the values from them all in sorted order. In other words: s1 = s2 = s3 = for value in ???(s1, s2, s3):
13
2020
by: Jack | last post by:
I have a class called "Base". This class has a protected member variable "m_base" which can be retrieved using the public member function "GetBaseMember". "m_base" is initialized to "1" and is never changed. I have another class which is a subclass of the "Base" class called "Derived". This derived class has a member variable called "m_derived". "m_derived" is initialized to "2" and is never changed. I pass an array of "Base" classes...
90
3466
by: John Salerno | last post by:
I'm a little confused. Why doesn't s evaluate to True in the first part, but it does in the second? Is the first statement something different? False print 'hi' hi Thanks.
21
1854
by: Bo Yang | last post by:
As long as I write c++ code, I am worry about the pointer. The more the system is, the dangerous the pointer is I think. I must pass pointers erverywhere, and is there a way to ensure that every object pointered by any pointer will be deleted and only be deleted once?
18
2121
by: desktop | last post by:
1) I have this code: std::list<intmylist; mylist.push_back(1); mylist.push_back(2); mylist.push_back(3); mylist.push_back(4);
0
1413
by: subramanian100in | last post by:
Suppose I have vector<intc; for (int i = 0; i < 10; ++i) c.push_back(i); vector<int>::iterator it = find(c.begin(), c.end(), 5); If I do, c.insert(c.begin(), 10);
0
9646
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 usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9484
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 synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
9957
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 choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8983
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 launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6742
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5386
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5518
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4055
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
3
2887
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.