473,594 Members | 2,747 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

More baby squeaking - iterators in a class

Hello Mr Everyone,

From:
http://docs.python.org/tut/node11.ht...00000000000000

"Define a __iter__() method which returns an object with a next()
method. If the class defines next(), then __iter__() can just return
self:"

The thing is, I tried to define __iter__() directly without explicit
defining next (after all, the conclusion from this passage should
be that it's possible).
class R:
def __init__(self, d):
self.d=d
self.i=len(d)
def __iter__(self):
if self.i == 0:
raise StopIteration
self.i -= 1
return self.d[self.i]

s=R('spam') dir(s) ['__doc__', '__init__', '__iter__', '__module__', 'd', 'i']

Apparently no, there is no next() method. Let's see
if iterator works:
s.__iter__() 'm' s.__iter__() 'a' s.__iter__() 'p' s.__iter__() 's' s.__iter__() Traceback (most recent call last):
File "<interacti ve input>", line 1, in ?
File "<interacti ve input>", line 7, in __iter__
StopIteration

OK, this part works. But this:
s=R('spam')
for i in s:

print i

Traceback (most recent call last):
File "<interacti ve input>", line 1, in ?
TypeError: __iter__ returned non-iterator of type 'str'

So which is it? Does next() method HAS to be defined
explicitly? That's what Wikipedia says:

http://en.wikipedia.org/wiki/Iterator#Python

"Any user defined class can support standard iteration (either
implicit or explicit) by defining an __iter__() method which creates
an iterator object. The iterator object then needs to define both an
__iter__() method as well as a next() method."


--
It's a man's life in a Python Programming Association.
Jul 18 '05 #1
13 1418
"Bulba!" <bu***@bulba.co m> wrote in message
news:nj******** *************** *********@4ax.c om...
Hello Mr Everyone,

From:
http://docs.python.org/tut/node11.ht...00000000000000

"Define a __iter__() method which returns an object with a next()
method. If the class defines next(), then __iter__() can just return
self:"

The thing is, I tried to define __iter__() directly without explicit
defining next (after all, the conclusion from this passage should
be that it's possible).
I don't get that from the passage quoted, at all, although it is somewhat
opaque. It says that your __iter__() method must *return an object* with a
next() method; your __iter__() method below doesn't return such an object,
but instead returns a string. It then says that *if* your class defines
next(), which yours doesn't, __iter__() can return self.

[spaces inserted; you should note that many newsreaders strip the TAB
character...]
class R:
def __init__(self, d):
self.d=d
self.i=len(d)
def __iter__(self):
if self.i == 0:
raise StopIteration
self.i -= 1
return self.d[self.i]


Solution: replace "__iter__" with "next" in the class definition above,
then add to the end:

def __iter__(self):
return self
--
I don't actually read my hotmail account, but you can replace hotmail with
excite if you really want to reach me.
Jul 18 '05 #2
Bulba! <bu***@bulba.co m> wrote:
So which is it? Does next() method HAS to be defined
explicitly?


It has to be defined, whether explicitly or not (e.g. via a generator).
Alex
Jul 18 '05 #3

"Bulba!" <bu***@bulba.co m> wrote in message
news:nj******** *************** *********@4ax.c om...
"Define a __iter__() method which returns an object with a next()
method. If the class defines next(), then __iter__() can just return
self:"

The thing is, I tried to define __iter__() directly without explicit
defining next (after all, the conclusion from this passage should
be that it's possible).
It is, see below.
class R:
def __init__(self, d):
self.d=d
self.i=len(d)
def __iter__(self):
if self.i == 0:
raise StopIteration
self.i -= 1
return self.d[self.i]


Change 'return' to 'yield'. Then r.__iter__() *will* return a
(generator)iter ator with a .next method, as required. But it will only
yield one value before running off the end. Since __iter__ is meant to be
called only once, you need to loop explicitly in the generator. For
instance

def __iter__(self):
i,d = self.i, self.d
while i
i =- 1
yield d[i]

Copying i makes the generator non-destuctive.

(PS, use spaces, not tabs, in posted code.)

Terry J. Reedy

Jul 18 '05 #4
Bulba! wrote:
Hello Mr Everyone,

From:
http://docs.python.org/tut/node11.ht...00000000000000

"Define a __iter__() method which returns an object with a next()
method. If the class defines next(), then __iter__() can just return
self:"

The thing is, I tried to define __iter__() directly without explicit
defining next (after all, the conclusion from this passage should
be that it's possible).
class R:
def __init__(self, d):
self.d=d
self.i=len(d)
def __iter__(self):
if self.i == 0:
raise StopIteration
self.i -= 1
return self.d[self.i]


Here's one way: # (Make __iter__ an iterator)

Py> class R1(object):
def __init__(self, data):
self.data = data
self.i = len(data)
def __iter__(self):
while self.i > 0:
self.i -= 1
yield self.data[self.i]

Py> s=R1('spam')
Py> list(s)
['m', 'a', 'p', 's']
Py> list(s)
[]
Py> s.i = 3
Py> list(s)
['a', 'p', 's']

Here's another way: # (Return something with __iter__ and next methods)

Py> class R2(object):
def __init__(self, data):
self.d = data
self.i = len(data)
def __iter__(self):
return iter(self.d)
Py> s = R2('spam')
Py> list(s)
['s', 'p', 'a', 'm']
Py> list(s)
['s', 'p', 'a', 'm']

--Scott David Daniels
Sc***********@A cm.Org
Jul 18 '05 #5
On Thu, 30 Dec 2004 12:06:31 -0800, Scott David Daniels
<Sc***********@ Acm.Org> wrote:
Here's one way: # (Make __iter__ an iterator)
Py> class R1(object):
def __init__(self, data):
self.data = data
self.i = len(data)
def __iter__(self):
while self.i > 0:
self.i -= 1
yield self.data[self.i]


Thanks to everyone for their responses, but it still doesn't work re
returning next() method:
class R3:
def __init__(self, d):
self.d=d
self.i=len(d)
def __iter__(self):
d,i = self.d, self.i
while i>0:
i-=1
yield d[i]
p=R3('eggs')
p.next() Traceback (most recent call last):
File "<interacti ve input>", line 1, in ?
AttributeError: R3 instance has no attribute 'next' dir(p) ['__doc__', '__init__', '__iter__', '__module__', 'd', 'i'] list(p) ['s', 'g', 'g', 'e']
I tried all the methods advised by you and other posters and they do
return an object with __iter__, but not with the next method.

What's strange is that when it comes to function, it does return
the .next method:

def rev(d):
for i in range (len(d)-1, -1, -1):
yield d[i]
o=rev('eggs')
o <generator object at 0x0120DF58> dir(o) ['__class__', '__delattr__', '__doc__', '__getattribute __',
'__hash__', '__init__', '__iter__', '__new__', '__reduce__',
'__reduce_ex__' , '__repr__', '__setattr__', '__str__', 'gi_frame',
'gi_running', 'next'] o.next() 's' o.next() 'g' o.next() 'g' o.next() 'e'
The function returns 'generator object', as shown above,
while p is a class instance:
p

<__main__.R3 instance at 0x0123CA58>


--
It's a man's life in a Python Programming Association.
Jul 18 '05 #6
Reread Russel Blau post he is spot on with his comments:
Russel Blau wrote:
I don't get that from the passage quoted, at all, although it is somewhatopaque. It says that your __iter__() method must *return an object* with anext() method; your __iter__() method below doesn't return such an object,but instead returns a string. It then says that *if* your class definesnext(), which yours doesn't, __iter__() can return self.

[spaces inserted; you should note that many newsreaders strip the TAB
character...]
class R:
def __init__(self, d):
self.d=d
self.i=len(d)
def __iter__(self):
if self.i == 0:
raise StopIteration
self.i -= 1
return self.d[self.i]
Solution: replace "__iter__" with "next" in the class definition above,then add to the end:

def __iter__(self):
return self

That works exactly as advertised.

py> s = R('54645656')
.... s.next()
'6'
.... s.next()
'5'
.... s.next()
'6'
.... s.next()
'5'
.... s.next()
'4'
... s.next()
'6'
.... s.next()
'4'
.... s.next()
'5'
.... s.next()
Traceback (most recent call last):
File "<input>", line 1, in ?
File "<input>", line 7, in next
StopIteration

And the other posters showed you how to create an iterator without a
next() .
Other than having no next() method they still work the same.

Jul 18 '05 #7

"Bulba!" <bu***@bulba.co m> wrote in message
news:bv******** *************** *********@4ax.c om...
Thanks to everyone for their responses, but it still doesn't work re
returning next() method:
class R3:
def __init__(self, d):
self.d=d
self.i=len(d)
def __iter__(self):
d,i = self.d, self.i
while i>0:
i-=1
yield d[i]
p=R3('eggs')
p.next()


This is the wrong test for what I and some others thought you were asking.
The requirement for p to be an *iterable* and useable in code such as 'for
i in p' is that iter(p), not p itself, have a .next method, and iter(p)
will. Try ip=iter(p) followed by ip.next and ip.next() instead.

If, for whatever reason, you instead want p to actually be an *iterator*
with a .next (or .getitem) method, then, of course, you have to actually
give it a .next (or .getitem) method.

Terry J. Reedy

Jul 18 '05 #8
Bulba! wrote:

Thanks to everyone for their responses, but it still doesn't work re
returning next() method:

class R3:
def __init__(self, d):
self.d=d
self.i=len(d)
def __iter__(self):
d,i = self.d, self.i
while i>0:
i-=1
yield d[i]

p=R3('eggs' )
p.next() [snip]
What's strange is that when it comes to function, it does return
the .next method:

def rev(d):
for i in range (len(d)-1, -1, -1):
yield d[i]

o=rev('eggs ') [snip]o.next()

's'


Note the difference here. When you're using the function, you call the
iter function (called rev in your example). When you're using the
class, you haven't called the iter function, only instantiated the class
(i.e. called the __init__ function). Try one of the following:

py> p = R3('eggs')
py> i = p.__iter__()
py> i.next()
's'

or

py> p = R3('eggs')
py> i = iter(p)
py> i.next()
's'

Steve
Jul 18 '05 #9
Terry Reedy wrote:
This is the wrong test for what I and some others thought you were asking.The requirement for p to be an *iterable* and useable in code such as 'fori in p' is that iter(p), not p itself, have a .next method, and iter(p)will. Try ip=iter(p) followed by ip.next and ip.next() instead. Does that mean if you dont't call iter(() on your instance or have a
next() method you can't do this: class R3:
def __init__(self, d):
self.d=d
self.i=len(d)
def __iter__(self):
d,i = self.d, self.i
while i>0:
i-=1
yield d[i]

p=R3('eggs')
for i in p:
print i


I am asking because I want to fully understand what makes an
*iterator*.

M.E.Farmer

Jul 18 '05 #10

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

Similar topics

3
6967
by: Alexander Stippler | last post by:
Hi, I have to design some two dimensional iterators and I'm not quite sure about the design. I'd like to have the iterators mostly STL-like. The STL does not contain two dimensional iterators, I think. I'm not sure, what is the best way of design and usage syntax. Is there a good reference or example online? How could such an iterator look like for the equivalent of std::vector, lets say my::matrix to "exploit" the pointers as iterators...
4
3534
by: Merlin | last post by:
Hi, I am a C++ developer and would like to implement container classes for various types of objects. I use MS Visual C++ to compile my code. Nevertheless I like to write code that is independent from MFC and intentionally I am trying to avoid inheriting from CList and CArray classes. Recently, I became familiar with iterators and have read many articles including the GOF description on what they help to achieve. My understanding so far...
4
1880
by: matthurne | last post by:
I am working through exercise 8-2 in Accelerated C++...I am implementing the function equal(b, e, b2) where b is an iterator for the first element in a container, e is an iterator pointing to one past the last element in that same container, and b2 is an iterator for the first element in the second container. Here's what I have: template <class T> bool equal(T begin, T end, T begin2) { while (begin != end) { if (*begin != *begin2) {
1
1891
by: Marcin Kaliciński | last post by:
template<class RanAccIt> void some_algorithm(RanAccIt begin, RanAccIt end) { // this algorithm involves calling std::lexicographical_compare // on range [begin, end), and on reverse of this range // (i.e. as rbegin, rend was passed) } How can I call lexicographical_compare inside the function so that it traverses the range backwards?
90
3394
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.
6
1592
by: gexarchakos | last post by:
Hi there, Please give me at least a hint... I have a problem implementing a function object with parameters two iterators. That is: A class 'node' produces messages using a routing policy. The routing policy needs to take the node's neighbours and return a subset of them based on several criteria. Each message may have different routing policy. Thus, the policy should be specified while the new message is
7
2310
by: desktop | last post by:
I am not sure I quite understand the use of iterators. I have this int array: int a = {1,2,3,4,5} I would now like to make an iterator to the first and last element: std::iterator<intiter; iter = a;
18
2101
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);
3
1535
by: Jess | last post by:
Hello, Iterators are typically put into five different categories, namely input iterator, output iterator, forward iterator, bidirectional iterator and random iterator. The differences come from the requirements each kind of iterator has to meet. Therefore, I think the five categories are kind of conceptual thing, i.e. they are not really C++ structs/classes etc, is this correct? There are some functions that return iterators. For...
0
7941
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
7874
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
8246
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
8368
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...
1
8000
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
1
5738
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
3895
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
1476
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
0
1205
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.