yield 的学习,模拟无限数据 ::-- ZoomQuiet [DateTime(2007-10-24T04:15:39Z)] TableOfContents
Include(CPUGnav) {{{Albert Lee <[email protected]> hide details 12:08 pm (2 minutes ago)
reply-to [email protected] to "Python.cn@google" <[email protected]> date Oct 24, 2007 12:08 PM subject [CPyUG:34110] yield 的学习,模拟无限数据 mailed-by googlegroups.com
}}}
1. yield 的学习,模拟无限数据
对haskell我最喜爱的特性是惰性计算和无限数据结构,以及函数组合。 这些特性在python中是否可以模拟出来呢? 今天作了一些尝试
python中提供了yield 和 decorators, 应当可以模拟出。
1.1. 尝试: 无限数据结构
haskell: [1..] Hugs> take 5 [1..] [1,2,3,4,5]
Python:
>>> def inf_list1(): i = 0 while 1: i += 1 yield i >>> def take(n, it): cnt = 0 for i in it(): cnt += 1 if cnt > n: break yield i >>> take(5, m) >>> [i for i in take(5, inf_list1)] [1, 2, 3, 4, 5]
Python 的 take 也实现为一个 generator ,这样的好处是可以串起来执行,比如,我要实现 haskell中的: Hugs> drop 3 $ take 5 [1..] [4,5]
- 那么再实现一个 drop 函数:
>>> def drop(n, it): t = 0 for i in it(): t += 1 if t > n: yield i >>> def m10(): for i in range(10): yield i >>> [i for i in drop(3, m10)] [3, 4, 5, 6, 7, 8, 9] >>> [i for i in take(5, m10)] [0, 1, 2, 3, 4] >>>
- 不过,在组合 take 和 drop 的时候遇到了麻烦
>>> drop(3, take(5, m10)) >>> [i for i in drop(3, take(5, m10))] Traceback (most recent call last): File "", line 1, in -toplevel- [i for i in drop(3, take(5, m10))] File "", line 3, in drop for i in it(): TypeError: 'generator' object is not callable >>>
- 修改下 drop, take 的定义如下:
>>> def take(n, it): cnt = 0 if callable(it): it=it() for i in it: cnt += 1 if cnt > n: break yield i >>> def drop(n, it): cnt = 0 if callable(it): it = it() for i in it: cnt += 1 if cnt > n: yield i >>> [i for i in take(2, drop(3, take(7, inf_list1)))] [4, 5] >>>
1.2. 对应 haskell
Hugs> take 2 $ drop 3 $ take 7 [1..] [4,5] Hugs>
基本达到目的。