Method returning an Iterable Object

2009-01-26 Thread Anjanesh Lekshminarayanan
Is there a way to return an iterable object ?

class twoTimes:
def __init__(self, n):
self.__n = n

def getNext():
self.__n *= 2
return self.__n


t = twoTimes(5)
while (n in t.getNext()): # while (n in t):
print (n)

-- 
Anjanesh Lekshmnarayanan
--
http://mail.python.org/mailman/listinfo/python-list


Re: Method returning an Iterable Object

2009-01-26 Thread Steve Holden
Anjanesh Lekshminarayanan wrote:
 Is there a way to return an iterable object ?
 
 class twoTimes:
 def __init__(self, n):
 self.__n = n
 
 def getNext():
 self.__n *= 2
 return self.__n
 
 
 t = twoTimes(5)
 while (n in t.getNext()): # while (n in t):
 print (n)
 
Sure:

class EveryOther:
def __init__(self, seq):
self.seq = seq self.idx = 0
def next(self):
self.idx += 1
if self.idx = len(self.seq):
raise StopIteration
value = self.seq[self.idx]
self.idx += 1
return value
def __iter__(self):
return self


print [x for x in EveryOther(range(10))
[1, 3, 5, 7, 9]

regards
 Steve
-- 
Steve Holden+1 571 484 6266   +1 800 494 3119
Holden Web LLC  http://www.holdenweb.com/

--
http://mail.python.org/mailman/listinfo/python-list


Re: Method returning an Iterable Object

2009-01-26 Thread Andreas Waldenburger
On Mon, 26 Jan 2009 22:01:21 +0530 Anjanesh Lekshminarayanan
m...@anjanesh.net wrote:

 Is there a way to return an iterable object ?
 
 class twoTimes:
 def __init__(self, n):
 self.__n = n
 
 def getNext():
 self.__n *= 2
 return self.__n
 
 
Rename getNext() to next() and create another method named __iter__()
that just returns self. TwoTimes is now an iterator.

You can also replace the whole class with a function thusly:

def two_times(n):
for k in itertools.count(1):
yield n * (2**k)

This function is then called a generator (because it generates an
iterator). You can now say

infinitely_doubling_numbers = two_times(2)
for number in in infinitely_doubling_numbers:
print number

to the same effect as the iterator version above.

python.org seems uncooperative at the moment, but look up iterators or
the iterator protocol and generators if it works for you.


 t = twoTimes(5)
 while (n in t.getNext()): # while (n in t):
 print (n)
 
You are aware that this is an infinite loop, as is my example above BTW?
(Probably just an example, but I ask just in case.)

Also, could it be that you mean for n in t?

regards
/W

-- 
My real email address is constructed by swapping the domain with the
recipient (local part).
--
http://mail.python.org/mailman/listinfo/python-list


Re: Method returning an Iterable Object

2009-01-26 Thread Anjanesh Lekshminarayanan
 You can also replace the whole class with a function thusly:

def two_times(n):
for k in itertools.count(1):
yield n * (2**k)

 This function is then called a generator (because it generates an
 iterator). You can now say

infinitely_doubling_numbers = two_times(2)
for number in in infinitely_doubling_numbers:
print number

Oh..this is new. Will checkup itertools. Thanks.

 t = twoTimes(5)
 while (n in t.getNext()): # while (n in t):
 print (n)

 You are aware that this is an infinite loop, as is my example above BTW?
 (Probably just an example, but I ask just in case.)

I was aware this was an infinite loop - just didnt want to put more
code for an example.
--
http://mail.python.org/mailman/listinfo/python-list


Re: Method returning an Iterable Object

2009-01-26 Thread Andreas Waldenburger
On Tue, 27 Jan 2009 00:05:53 +0530 Anjanesh Lekshminarayanan
m...@anjanesh.net wrote:

  You can also replace the whole class with a function thusly:
 
 def two_times(n):
 for k in itertools.count(1):
 yield n * (2**k)
 
  This function is then called a generator (because it generates an
  iterator). You can now say
 
 infinitely_doubling_numbers = two_times(2)
 for number in in infinitely_doubling_numbers:
 print number
 
 Oh..this is new. Will checkup itertools. Thanks.
 
OK, happy I could help. But my point was the yield statement (in case
you didn't know about yield).

regards
/W

-- 
My real email address is constructed by swapping the domain with the
recipient (local part).
--
http://mail.python.org/mailman/listinfo/python-list


Re: Method returning an Iterable Object

2009-01-26 Thread Anjanesh Lekshminarayanan
But how come a raise StopIteration in the next() method doesnt need to
be caught ? It works without breaking.

class twoTimes:
max = 10**10

def __init__(self, n):
self.__n = n

def next(self):
if self.__n  self.max:
raise StopIteration
self.__n *= 2
return self.__n

def __iter__(self):
return self


t = twoTimes(5)
c = 0

print (t.next())
print (t.next())

for n in t:
print n


Anjanesh
--
http://mail.python.org/mailman/listinfo/python-list


Re: Method returning an Iterable Object

2009-01-26 Thread James Mills
On Tue, Jan 27, 2009 at 1:16 PM, Anjanesh Lekshminarayanan
m...@anjanesh.net wrote:
 But how come a raise StopIteration in the next() method doesnt need to
 be caught ? It works without breaking.

Because this exception is specially dealt
with when iterating over an iterator. The
raise StopIteration is what causes the
iteration to stop.

Consider:

 x = EveryOther(xrange(10))
 x.next()
0
 x.next()
2
 x.next()
4
 x.next()
6
 x.next()
8
 x.next()
Traceback (most recent call last):
  File stdin, line 1, in module
  File foo.py, line 12, in next
raise StopIteration
StopIteration
 x = EveryOther(xrange(10))
 list(x)
[0, 2, 4, 6, 8]


cheers
James
--
http://mail.python.org/mailman/listinfo/python-list


Re: Method returning an Iterable Object

2009-01-26 Thread Terry Reedy

Anjanesh Lekshminarayanan wrote:

But how come a raise StopIteration in the next() method doesnt need to
be caught ? It works without breaking.


The for-loop looks for and catches StopIteration.  It is an essential 
part of what defines a finite iterator.
(Note, in 3.0, next is renamed __next__ in conformance with all other 
special methods.  In 2.6, the rename is optional, I believe.)



class twoTimes:
max = 10**10

def __init__(self, n):
self.__n = n


There is no reason to mangle the attribute name.
Max should be a parameter, and self.max = max added to the init.



def next(self):
if self.__n  self.max:
raise StopIteration
self.__n *= 2
return self.__n


Are you sure you do not want to return once the initial value of n 
passed to init?


def __iter__(self):
return self


Once you understand the above, you can rewrite it as a generator function:

def two_times(num, stop):
  while num  stop:
yield num
num *=2

The two last lines can be switches if desired.


t = twoTimes(5)
c = 0

print (t.next())
print (t.next())

for n in t:
print n


 print(list(two_times(5,687)))
[5, 10, 20, 40, 80, 160, 320, 640]

Terry Jan Reedy

--
http://mail.python.org/mailman/listinfo/python-list