[Tutor] PolyRange -- iterator
by Spir other posts by this author
Nov 4 2009 8:44AM messages near this date
[Tutor] probando el email / mail test
|
Re: [Tutor] PolyRange -- iterator
Hello,
as I was crawling in endless complications with unadequate ranges, I decided to create a "Po
lyRange" type able to hold arbitrary many "sub-range"; which means finally a big range with
wholes in it. This whole stuff again to cope with unicode -- a poly-range would be able to h
old a range for a char class (eg 'letter') which spans over several ordinal ranges. (Viva un
icode consortium!)
So, it works as needed. It is even able to "stretch" over addictional sub-ranges or to "unit
e" with a poly-range brother (sister, too). See code below.
Now, I need it to be properly iterable if needed -- the main use beeing indeed the 'in' oper
ator -- but who knows. So, I tried to implement __iter__ and next (by the way, why isin't it
called __next__ instead, looks strange for a python builtin?). Seems to work, but the resul
t looks veeery heavy to my eyes. As I had never written an iterator before, would be nice an
d criticize the code?
Thank you,
Denis
-------
la vita e estrany
==========================================================
class PolyRange(object):
def __init__(self, *bounds):
''' Build list of ranges from bounds.
* bounds must sequence of (n1,n2) pairs. '''
self.bounds = list(bounds)
self.ranges = [xrange(n1,n2) for (n1,n2) in bounds]
# iteration
def __contains__(self, item):
''' x in self '''
for range in self.ranges:
if item in range:
return True
def __or__(self, other):
''' PolyRange union '''
bounds = self.bounds + other.bounds
return PolyRange(*bounds)
def __add__(self, range):
''' PolyRange with new range added '''
n1 = range[0] ; n2 = n1+len(range)
bounds = self.bounds + [(n1,n2)]
return PolyRange(*bounds)
def __iter__(self):
self.isEmpty = False
(self.range_index, self.item_index) = (0,0)
self.iter = self.ranges[0].__iter__()
return self
def next(self):
# case already emptied
if self.isEmpty:
raise StopIteration
# throw next item
try:
item = self.iter.next()
except StopIteration:
self.range_index += 1
self.item_index = 0
else:
self.item_index += 1
return item
# next range
if len(self.ranges) > self.range_index:
self.iter = self.ranges[self.range_index].__iter__()
else:
self.empty = True
raise StopIteration
# throw item
try:
item = self.iter.next()
except StopIteration:
self.empty = True
raise StopIteration
else:
self.item_index += 1
return item
def __str__(self):
return "(%s)" %'U'.join("[%s,%s)" %(n1,n2) for (n1,n2) in self.bounds)
def __repr__(self):
return "PolyRange(%s)" %', '.join(str(b) for b in self.bounds)
return False
def testPolyRange():
print "=== base case -- test in/contains"
pr = PolyRange((1,3),(5,7),(9,11))
print "%s\t%s" %(pr,repr(pr))
print 2 in pr, 4 in pr
print "=== union"
pr = PolyRange((1,3),(5,7)) | PolyRange((9,11))
print pr
print "=== addition, iteration"
r = xrange(3,9)
pr0 = PolyRange((1,3),(5,7))
pr1 = pr0 + r
print pr1
for i in pr1: print i,
testPolyRange()
_______________________________________________
Tutor maillist - Tutor@[...].org
To unsubscribe or change subscription options:
http://mail.python.org/mailman/listinfo/tutor
Thread:
Spir
Hugo Arts
Spir
Hugo Arts
Stefan Lesicnik
|