bebraw
9/24/2011 - 10:43 AM

## Infinite list for python

Infinite list for python

``````from inf import InfList
from tests import pos_l, neg_l

def lazy_zip(a, b):
if isinstance(a, InfList) and isinstance(b, InfList):
return InfList([a[0], b[0]], [a[1], b[1]], lambda i, x, y: [a[i], b[i]])

return old_zip(a, b);

old_zip = zip
zip = lazy_zip

zip_l = zip(pos_l, neg_l)
assert zip_l[0] == [1, -1]
assert zip_l[1] == [2, -2]

zip_hybrid = zip(pos_l, range(3, 5))
assert zip_hybrid == [(1, 3), (2, 4)]

def concat(a):
# concat just zipped InfLists for now... might want to generalize
return InfList(a[0][0], a[0][1], lambda i, x, y: a[i / 2][i % 2])

concat_l = concat(zip(pos_l, neg_l))
assert concat_l[0] == 1
assert concat_l[1] == -1
assert concat_l[2] == 2
assert concat_l[3] == -2
assert concat_l[4] == 3
assert concat_l[5] == -3

def lazy_map(f, a):
if isinstance(a, InfList):
return InfList(f(a[0]), f(a[1]), lambda i, x, y: f(a[i]))

return old_map(f, a)

old_map = map
map = lazy_map

map_l = map(lambda a: a * 2, pos_l)
assert map_l[0] == 2
assert map_l[1] == 4

def lazy_filter(f, a):
if isinstance(a, InfList):
def valid():
i = 0
while True:
if f(a[i]):
yield a[i]

i += 1

valids = valid()

return InfList(valids.next(), valids.next(), lambda i, x, y: valids.next())

return old_filter(f, a)

old_filter = filter
filter = lazy_filter

filter_l = filter(lambda a: a % 2, pos_l)
assert filter_l[0] == 1, filter_l[0]
assert filter_l[1] == 3, filter_l[1]``````
``````from inf import InfList

pos_l = InfList(1, 2)
assert pos_l[0] == 1
assert pos_l[1] == 2
assert pos_l[2] == 3
assert pos_l[3] == 4

neg_l = InfList(-1, -2)
assert neg_l[0] == -1
assert neg_l[1] == -2
assert neg_l[2] == -3
assert neg_l[3] == -4

fibo = InfList(0, 1, lambda i, a, b: a + b)
assert fibo[0] == 0
assert fibo[1] == 1
assert fibo[2] == 1
assert fibo[3] == 2
assert fibo[4] == 3

# slice
assert fibo[1:4] == [1, 1, 2]``````
``````class InfList(object):
def __init__(self, *items):
self._rule = (lambda i, a, b: 2 * b - a) if len(items) == 2 else items[2]
self._items = list(items[0:2])

def __getitem__(self, k):
if k >= len(self._items):
self._calc_items(k)

return self._items[k]

def _calc_items(self, limit):
if isinstance(limit, slice):
limit = limit.stop

for i in xrange(len(self._items), limit + 1):
new_val = self._rule(i, self[-2], self[-1])
self._items.append(new_val)

def __unicode__(self):
self._calc_items(3)
f0, f1, f2 = map(unicode, self._items[:3])
return '[' + f0 + ', ' + f1 + ', ' + f2 + ', ..]'
``````