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 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
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
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 ?
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
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.
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>
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.
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>
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 This thread has been closed and replies have been disabled. Please start a new discussion. Similar topics |
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.
};
|
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
|
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.
|
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):
|
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...
| |
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.
|
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?
|
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);
|
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);
|
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...
|
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,...
| |
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...
|
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...
|
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();...
|
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...
|
by: adsilva |
last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
|
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
| |
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...
| |