473,718 Members | 2,125 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

What makes an iterator an iterator?

I thought that an iterator was any object that follows the iterator
protocol, that is, it has a next() method and an __iter__() method.

But I'm having problems writing a class that acts as an iterator. I have:

class Parrot(object):
def __iter__(self):
return self
def __init__(self):
self.next = self._next()
def _next(self):
for word in "Norwegian Blue's have beautiful plumage!".split ():
yield word

But this is what I get:
>>P = Parrot()
for word in P:
.... print word
....
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: iter() returned non-iterator of type 'Parrot'

Why is my instance not an iterator?

But I can do this:
>>for word in P.next:
.... print word
....
Norwegian
Blue's
have
beautiful
plumage!

I find myself perplexed as to this behaviour.
--
Steven D'Aprano

Apr 18 '07 #1
27 5312
I V
On Wed, 18 Apr 2007 15:39:22 +1000, Steven D'Aprano wrote:
I thought that an iterator was any object that follows the iterator
protocol, that is, it has a next() method and an __iter__() method.
....
class Parrot(object):
....
def __init__(self):
self.next = self._next()
self.next isn't a method here, it's a generator. You could do:

def __init__(self):
self.next = self._next().ne xt

But, having tested, that doesn't appear to work either - I think
this is because, again, self.next is not strictly a method, it's an
attribute that happens to be callable.

The python manual gives you a possible solution:

---QUOTE http://docs.python.org/lib/typeiter.html ---
Python's generators provide a convenient way to implement the iterator
protocol. If a container object's __iter__() method is implemented as a
generator, it will automatically return an iterator object (technically, a
generator object) supplying the __iter__() and next() methods.
---END QUOTE---

i.e., just rename your _next function to __iter__ . Your class won't
itself be an iterator, but it will be usable in for statements and so one,
and convertable to an iterator with the iter builtin.
Apr 18 '07 #2
Steven D'Aprano <st***@REMOVEME .cybersource.co m.auwrites:
class Parrot(object):
def __iter__(self):
return self
def __init__(self):
self.next = self._next()
def _next(self):
for word in "Norwegian Blue's have beautiful plumage!".split ():
yield word
Clearly the problem is you've misused an apostrophe. Python doesn't
like the plural getting an apostrophe.

<URL:http://www.angryflower .com/bobsqu.gif>

--
\ "Speech is conveniently located midway between thought and |
`\ action, where it often substitutes for both." -- John Andrew |
_o__) Holmes, _Wisdom in Small Doses_ |
Ben Finney
Apr 18 '07 #3
on 18.04.2007 07:39 Steven D'Aprano said the following:
I thought that an iterator was any object that follows the iterator
replace object with "instance of a class", i.e. the relevant methods are
looked up in the __class__ not in the instance (I think).
I had the same troubles trying to dynamically reassign a __call__ method...
protocol, that is, it has a next() method and an __iter__() method.

But I'm having problems writing a class that acts as an iterator. I have:

class Parrot(object):
def __iter__(self):
return self
def __init__(self):
self.next = self._next()
def _next(self):
for word in "Norwegian Blue's have beautiful plumage!".split ():
yield word
Try this::

class Parrot(object):
def __iter__(self):
return self
def __init__(self):
self.__class__. next = self._next().ne xt # see post by I V
def _next(self):
for word in "Norwegian Blue's have beautiful plumage!".split ():
yield word

This works but practically forces the class to be used as a singleton...
not very helpful :)

Better:

* use the '__iter__ returns/is a generator' way,
* or if you need the object to be the iterator, implement the next
method directly on the class::

class Parrot(object):
def _next(self):
for word in "Norwegian Blue's have beautiful plumage!".split ():
yield word
def __iter__(self):
self.generator = self._next()
return self
def next(self):
return self.generator. next()

cheers,
stefan

Apr 18 '07 #4
On Wed, 18 Apr 2007 16:58:23 +1000, Ben Finney wrote:
Steven D'Aprano <st***@REMOVEME .cybersource.co m.auwrites:
>class Parrot(object):
def __iter__(self):
return self
def __init__(self):
self.next = self._next()
def _next(self):
for word in "Norwegian Blue's have beautiful plumage!".split ():
yield word

Clearly the problem is you've misused an apostrophe. Python doesn't
like the plural getting an apostrophe.

<URL:http://www.angryflower .com/bobsqu.gif>
I thought the rule wa's that any time you 'see an 'S, you put an
apo'strophe before it. If that's wrong, 'shouldn't it rai'se an exception?


--
'Steven D'Aprano
Apr 18 '07 #5
On Wed, 18 Apr 2007 06:13:39 +0000, I V wrote:
On Wed, 18 Apr 2007 15:39:22 +1000, Steven D'Aprano wrote:
>I thought that an iterator was any object that follows the iterator
protocol, that is, it has a next() method and an __iter__() method.
[snip]
i.e., just rename your _next function to __iter__ . Your class won't
itself be an iterator, but it will be usable in for statements and so one,
and convertable to an iterator with the iter builtin.

Thanks to all those who helped, this fixed my problem.

For the record, this is what I actually wanted: a four-line self-sorting
dictionary:

class SortedDict(dict ):
def __iter__(self):
for key in sorted(self.key s()):
yield key

Note that using sorted(self) does not work.

Iterating over a SortedDictionar y returns the keys in sorted order. This
minimalist implementation doesn't sort the values, items or string
representation of the dict, but they should be easy to implement.

--
Steven D'Aprano

Apr 18 '07 #6
On Apr 18, 3:32 am, Steven D'Aprano <s...@REMOVEME. cybersource.com .au>
wrote:
On Wed, 18 Apr 2007 06:13:39 +0000, I V wrote:
On Wed, 18 Apr 2007 15:39:22 +1000, Steven D'Aprano wrote:
I thought that an iterator was any object that follows the iterator
protocol, that is, it has a next() method and an __iter__() method.

[snip]
i.e., just rename your _next function to __iter__ . Your class won't
itself be an iterator, but it will be usable in for statements and so one,
and convertable to an iterator with the iter builtin.

Thanks to all those who helped, this fixed my problem.

For the record, this is what I actually wanted: a four-line self-sorting
dictionary:

class SortedDict(dict ):
def __iter__(self):
for key in sorted(self.key s()):
yield key

Note that using sorted(self) does not work.

Iterating over a SortedDictionar y returns the keys in sorted order. This
minimalist implementation doesn't sort the values, items or string
representation of the dict, but they should be easy to implement.

--
Steven D'Aprano
Very neat. Why not this?

class SortedDict(dict ):
def __iter__(self):
return iter(sorted(sel f.keys()))

-- Paul

Apr 18 '07 #7
Steven D'Aprano wrote:
class SortedDict(dict ):
****def*__iter_ _(self):
********for*key *in*sorted(self .keys()):
************yie ld*key

Note that using sorted(self) does not work.
That's because sorted() invokes __iter__() if present. To prevent the
recursion you can explicitly invoke dict.__iter__() :
>>class SortedDict(dict ):
.... def __iter__(self):
.... return iter(sorted(sup er(SortedDict, self).__iter__( )))
....
>>sd = SortedDict(a=1, b=2, c=3)
list(sd)
['a', 'b', 'c']

Note that a list of keys is still built before the first key is yielded,
and, unlike dict, you can modify your SortedDict while iterating over it:
>>for k in sd:
.... if k == "b": sd["x"] = 42
....
>>sd
{'a': 1, 'x': 42, 'c': 3, 'b': 2}

whereas:
>>d = dict(a=1, b=2, c=3)
for k in d:
.... if k == "b": d["x"] = 42
....
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
RuntimeError: dictionary changed size during iteration

By the way, I think it would be worthwile to change super() to allow
e. g. super(SomeClass , self)[...] as an alternate spelling for
super(SomeClass , self).__getitem __(...) etc. With such an enhancement
SortedDict would become

class SortedDict(dict ):
def __iter__(self):
# doesn't work in current Python
iter(sorted(sup er(SortedDict, self)))
Peter

Apr 18 '07 #8
Stefan Rank schrieb:
on 18.04.2007 07:39 Steven D'Aprano said the following:
>I thought that an iterator was any object that follows the iterator

replace object with "instance of a class", i.e. the relevant methods are
looked up in the __class__ not in the instance (I think).
I had the same troubles trying to dynamically reassign a __call__ method...
This is correct.

It's not properly documented though, and not applied consistently, e.g.
__enter__ and __exit__ are looked up in the instance itself.

Georg

Apr 18 '07 #9
>
class Parrot(object):
def __iter__(self):
return self
def __init__(self):

Typo right here!!!!
self.next = self._next()
write:
self.next = self._next

no parenthesis.
def _next(self):
for word in "Norwegian Blue's have beautiful plumage!".split ():
yield word

See previous explanation.

thanks,

- Isaac.

Apr 18 '07 #10

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

Similar topics

0
1382
by: CoolPint | last post by:
I am trying to write a generic heapsort (of course as a self-exercise) with Iterator interface: something like blow.... But I got into trouble finding out the Iterator to the Child node. If indexing was used, I could do something like child = hole * 2 + 1; but since only thing the function accepts are random access Iterators, how do I calculate the Iterator to the child node? template <typename Iterator, typename Functor> void...
26
1514
by: Michael Klatt | last post by:
I am trying to write an iterator for a std::set that allows the iterator target to be modified. Here is some relvant code: template <class Set> // Set is an instance of std::set<> class Iterator { public : typedef typename Set::value_type T; typedef typename Set::iterator SetIterator; Iterator(Set& container, const SetIterator& it);
12
3301
by: Steven T. Hatton | last post by:
This is something I've been looking at because it is central to a currently broken part of the KDevelop new application wizard. I'm not complaining about it being broken, It's a CVS images. Such things happen. The whole subsystem is going through radical changes. I don't really want to say what I think of the code just yet. That would influence the opinions of others, and I really want to know how other people view these things,...
0
1944
by: nick | last post by:
Hi, I need to manage a "layered" collection of objects, where each layer grows independently, e.g, o--+--+--+--+--+ 1st layer | o 2nd layer (empty) | o--+--+--+ 3rd layer |
2
8742
by: yyhhjj | last post by:
I created a test program to implement an iterator. First, I used 'yield break' in the iterator, it worked normally. Then, I simply used 'break' in the places of 'yield break', it still worked normally. What's the difference between 'yield break' and 'break' here? Thanks!
19
4272
by: gsteff | last post by:
I'm a computer science student, and have recently been trying to convince the professor who teaches the programming language design course to consider mentioning scripting languages in the future. Along those lines, I've been trying to think of features of Python, and scripting languages in general, that can't be found in older languages, and have been having a surprising amount of trouble. Dynamic typing can be found in Smalltalk, the...
14
4874
by: shawnk | last post by:
I searched the net to see if other developers have been looking for a writable iterator in C#. I found much discussion and thus this post. Currently (C# 2) you can not pass ref and out arguments to an iterator method (one returning IEnumerable). I WOULD like to do this for transformative operations on a collection. I realize the need to lock target, etc. Does anyone know how to handle 'writable iterators' in C# 2?
7
1915
by: PengYu.UT | last post by:
I'm wondering is the standard defined behavior of past bound iterator. In the following example it seems that afer first "--it", it point to -1 index. I'm wondering if it is true independent of which STL implementation that I am using. #include <iostream> #include <vector>
123
6458
by: plenty900 | last post by:
I was looking over someone's C++ code today and despite having written perfectly readable C++ code myself, the stuff I was looking at was worse than legalese. The people who are guiding the development of C++ have really made a mess of things, I mean templates and competing libraries and all that just render the code impossible to comprehend. Sure there is going to be a certain amount of complexity, that's a given, but if code is not...
0
8827
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
8723
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
9354
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. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
9207
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 captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
9053
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
5971
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
4741
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
3182
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
2122
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.