Differences between revisions 1 and 3 (spanning 2 versions)
Revision 1 as of 2007-10-24 04:15:39
Size: 2417
Editor: ZoomQuiet
Comment:
Revision 3 as of 2007-10-24 04:59:57
Size: 4256
Editor: ZoomQuiet
Comment:
Deletions are marked like this. Additions are marked like this.
Line 17: Line 17:

= yield 的学习,模拟无限数据 =
= FPy 模拟 =
== yield 的学习,模拟无限数据 ==
Line 24: Line 24:
== 尝试: 无限数据结构 == === 尝试: 无限数据结构 ===
Line 109: Line 109:
== 对应 haskell == === 对应 haskell ===
Line 118: Line 118:

=== 用itertools模块更简单 ===
{{{Qiangning Hong <[email protected]> hide details 12:57 pm (8 minutes ago)
 reply-to [email protected]
 to [email protected]
 date Oct 24, 2007 12:57 PM
 subject [CPyUG:34115] Re: yield 的学习,模拟无限数据:
}}}

{{{!python
import sys
from itertools import count, islice

def inf_list():
   return count(1)

def take(n, it):
   return islice(it, n)

def drop(n, it):
   return islice(it, n, sys.maxint)

list(take(5, inf_list()) -> [1, 2, 3, 4, 5]
list(drop(3, take(5, inf_list()))) -> [4, 5]
list(take(2, drop(3, take(7, count(1))))) -> [4, 5]
}}}


== 函数的组合 ==
比较简单:{{{
Hugs> ((*2) . (+3)) 5
16
}}}
 * 在Python{{{
>>> def m2(x):
       return x * 2

>>> def add3(x):
       return x + 3

>>> def compose(f, g):
       return lambda x:f(g(x))

>>> compose(m2, add3)
<function <lambda> at 0x012875F0>
>>> compose(m2, add3)(5)
16
>>>
}}}

=== 对compose的装饰: ===
`infix 来自 cookbook`
{{{
class Infix:
   def __init__(self, function):
       self.function = function
   def __ror__(self, other):
       return Infix(lambda x, self=self, other=other: self.function(other, x))
   def __or__(self, other):
       return self.function(other)
   def __rlshift__(self, other):
       return Infix(lambda x, self=self, other=other: self.function(other, x))
   def __rshift__(self, other):
       return self.function(other)
   def __call__(self, value1, value2):
       return self.function(value1, value2)

# compose
def compose(f, g):
   return lambda x:f(g(x))

o=Infix(compose)

add2 = lambda x:x+2
multi3 = lambda x:x*3
new_f = add2 |o| multi3
print new_f(3)

---

>>> (add2 <<o>> multi3) (3)
11
}}}
已经比较接近了

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. FPy 模拟

1.1. yield 的学习,模拟无限数据

对haskell我最喜爱的特性是惰性计算和无限数据结构,以及函数组合。 这些特性在python中是否可以模拟出来呢? 今天作了一些尝试

python中提供了yield 和 decorators, 应当可以模拟出。

1.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.1.2. 对应 haskell

Hugs> take 2 $ drop 3 $ take 7 [1..]
[4,5]
Hugs>

基本达到目的。

1.1.3. 用itertools模块更简单

{{{Qiangning Hong <[email protected]> hide details 12:57 pm (8 minutes ago)

}}}

{{{!python import sys from itertools import count, islice

def inf_list():

  • return count(1)

def take(n, it):

  • return islice(it, n)

def drop(n, it):

  • return islice(it, n, sys.maxint)

list(take(5, inf_list()) -> [1, 2, 3, 4, 5] list(drop(3, take(5, inf_list()))) -> [4, 5] list(take(2, drop(3, take(7, count(1))))) -> [4, 5] }}}

1.2. 函数的组合

比较简单:

Hugs> ((*2) . (+3)) 5
16
  • 在Python

    >>> def m2(x):
           return  x * 2
    
    >>> def add3(x):
           return x + 3
    
    >>> def compose(f, g):
           return lambda x:f(g(x))
    
    >>> compose(m2, add3)
    <function <lambda> at 0x012875F0>
    >>> compose(m2, add3)(5)
    16
    >>>

1.2.1. 对compose的装饰:

infix 来自 cookbook

class Infix:
   def __init__(self, function):
       self.function = function
   def __ror__(self, other):
       return Infix(lambda x, self=self, other=other: self.function(other, x))
   def __or__(self, other):
       return self.function(other)
   def __rlshift__(self, other):
       return Infix(lambda x, self=self, other=other: self.function(other, x))
   def __rshift__(self, other):
       return self.function(other)
   def __call__(self, value1, value2):
       return self.function(value1, value2)

# compose
def compose(f, g):
   return lambda x:f(g(x))

o=Infix(compose)

add2 = lambda x:x+2
multi3 = lambda x:x*3
new_f = add2 |o| multi3
print new_f(3)

---

>>> (add2 <<o>> multi3) (3)
11

已经比较接近了

1.3. 反馈

PageComment2

MicroProj/2007-10-24 (last edited 2009-12-25 07:12:34 by localhost)