python delayed execution
要在Lisp中将流实现为延迟列表,建议使用Lisp宏。
1 2 3 4 5 | (defmacro cons-stream (a b) (cons ,a (delay ,b))) (defmacro delay (expr) `(memo-proc (lambda () ,expr))) |
用Python和Perl的方法做同样的事情会是什么?
编辑。有没有可能使用像streams这样的酷结构
1 | (define primes (sieve (integers-starting-from 2))) |
号
在Python和Perl等语言中
在Python中,最接近的结构可能是一个生成器表达式。
在Perl中,没有本地的懒惰列表,但是语言提供了构建一个列表所需的所有原语。我已经编写了一个名为list::gen的惰性列表库,该库在CPAN上可用。
1 2 3 4 5 | use List::Gen '*'; my $primes = <2..>->filter(\&is_prime); # where you provide &is_prime say"@$primes[0..10]"; # lazily finds the first 11 primes |
珀尔
runrig提出了来自mark dominus优秀的高阶Perl的技术。使用Hop免费提供的样本代码中的流模块,Etatostenes的筛子是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #! /usr/bin/env perl use strict; use warnings; use Stream qw/ filter head node promise show tail upfrom /; use subs 'sieve'; # no parens on recursive calls sub sieve { my($s) = @_; my $n = head $s; node $n, promise { sieve filter { $_[0] % $n != 0 } tail $s }; } sub primes { sieve upfrom 2 } show primes, 10; |
号
输出:
1 2 | $ ./primes 2 3 5 7 11 13 17 19 23 29 |
Python
Alexbow从Gist中借用代码,使用流的python中的筛子是
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #! /usr/bin/env python null_stream = (None, None) def reduce(f, result, stream): if stream is null_stream: return result return reduce(f, f(result, head(stream)), tail(stream)) def take(N, stream): if N <= 0 or stream is null_stream: return null_stream return (head(stream), lambda: take(N-1, tail(stream))) def filter(pred, stream): if stream is null_stream: return null_stream if pred(head(stream)): return (head(stream), lambda: filter(pred, tail(stream))) return filter(pred, tail(stream)) def integers_from(N): return (N, lambda: integers_from(N+1)) def head((H, _)): return H def tail((_, T)): return T() def to_array(stream): return reduce(lambda a, x: a + [x], [], stream) def sieve(stream): if stream is null_stream: return null_stream h = head(stream) return (h, lambda: sieve(filter(lambda x: x%h != 0, tail(stream)))) def primes(): return sieve(integers_from(2)) print to_array(take(10, primes())) |
。
输出:
1 2 | $ ./prymes [2, 3, 5, 7, 11, 13, 17, 19, 23, 29] |
其他可能性
在某些语言中,流模式是不可见的。例如,延迟评估是haskell的一个特性,因此您可以将
1 2 3 4 5 | primes = sieve [2 ..] where sieve (x:xs) = let remains = filter (not . isMultipleOf x) xs in x : sieve remains isMultipleOf a b = b `mod` a == 0 |
。
在Perl中,您将使用匿名子例程(如Lisp的lambda)。在高阶Perl的第6章中有很多例子
尽管很难说清楚你到底想要什么,因为不同语言之间的许多东西都有细微的不同,你要寻找的等价于python的东西可能是一个生成器,它是一种可以被要求生成下一个值然后挂起自身的函数。它们以前在(例如)中介绍过,您可以使用Python生成器函数做什么?还有很多例子和教程可以在其他地方找到——例如,http://www.dabeaz.com/generators/index.html