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 + ', ..]'