Functional programmers often miss lazy list when coding in a popular language. In some circumstances, they can make do with Python generators. An even better news is that from 2.3, Python provides
itertools library, which contains the old friends: cycle, repeat, takeWhile, dropWhile ... such that
takeWhile (<10) [1..]
translates to
>>> list(takewhile (lambda x:x<10,count(1)))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Now if the library is short for your need, we can resort to yield statements in python. Suppose we want to enumerate ways of splitting a list into two parts.
>>> list(splits ([1,2,3]))
[([1, 2, 3], []), ([2, 3], [1]), ([1, 3], [2]), ([3], [1, 2]), ([1, 2], [3]), ([2], [1, 3]), ([1], [2, 3]), ([], [1, 2, 3])]
In Haskell it will be
splits [] = [([],[])]
splits (x:xs) = concatMap expand $ splits xs
where expand (a,b) = [(x:a,b),(a,x:b)])
In Python it will be
def splits(l):
if l==[]:yield ([],[])
else:
x,xs=l[0],l[1:]
for (a,b) in splits(xs):
yield ([x]+a,b)
yield (a,[x]+b)
Quite literate, isn't it!
No comments:
Post a Comment