pyhton函数——黑板客老师课程学习

1、基本语法

  语法:

    def func_name (arguments)  定义

      statements

      return x,y

    x,y=func_name(para)   调用

  作用域:

    

    可以给内置的函数赋值,赋值之前是函数,赋值之后是变量。查找的时候先看是否自定义过,没有的话,再找是否是内置的。

    

    将出错的print注释掉

    

    

    global x,定义了x为全局变量,一旦更改,所有的都更改了。——注意的是这里的global x是在函数里边定义的,照样可以修改,牵一发动全身。

    

 

    如果执行的程序不是__main__则不会执行下边的语句。去掉not,来用作测试的时候使用的。上边图片应该不用“not”的,以此来用测试所编写的函数。

    基本语法——参数

      arguments

      def f1(a,b=2,c=3):

        print a,b,c

      

      *arg**kargs——跟无限多参数

      def f2(s,*args,**kargs):#args是不命名的参数,用元组表示,kargs是命名的参数

      print args

      def g(a,*args,**kargs):

        print a,args,kargs

      f2(1,2,3,4)

      g(1,2,3,4),g(1,2,3,b=5,c=6)

       

      二分法例子

        math

          import math

          math.sqrt(20.0)

        自己写函数

          0——————————————————————20

          0————————————10

          0——————5

              2.5——5

          ……

          注意区分整数还是小数,故要把右边最大值设为maxx,1)。

 

#!/usr/bin/env python
# coding: utf-8
#copyRight by heibanke

def sqrt_func(x, small):
    #check input
    assert x>=0
    assert small>0
    
    #init value
    loops = 1
    low = 0.0
    high = max(x,1)#非常关键,如果我们用high=x的时候,只能处理大于1的数,巧妙!
    while True and loops<=100:
        guess = (low+high)/2
        #2fen
        if abs(guess**2-x)<small:
            break
        elif guess**2 < x:
            low = guess
        else:
            high = guess
                    
        print low,high,guess
        loops+=1
        
    return guess,loops


if __name__=="__main__": 

    small_value = 0.0000001 
    test_data = [10.0, 23, 25, 0, 2, 0.25, 0.5] 
    for x in test_data: 
        y,loops=sqrt_func(x,small_value) 
        assert abs(y**2-x)<small_value, "Error occur in "+str(x) 
    
    print "Pass"

 

运行结果:

0.0 5.0 5.0
2.5 5.0 2.5
2.5 3.75 3.75
3.125 3.75 3.125
3.125 3.4375 3.4375
3.125 3.28125 3.28125
3.125 3.203125 3.203125
3.125 3.1640625 3.1640625
3.14453125 3.1640625 3.14453125
3.154296875 3.1640625 3.154296875
3.1591796875 3.1640625 3.1591796875
3.16162109375 3.1640625 3.16162109375
3.16162109375 3.16284179688 3.16284179688
3.16223144531 3.16284179688 3.16223144531
3.16223144531 3.16253662109 3.16253662109
3.16223144531 3.1623840332 3.1623840332
3.16223144531 3.16230773926 3.16230773926
3.16226959229 3.16230773926 3.16226959229
3.16226959229 3.16228866577 3.16228866577
3.16226959229 3.16227912903 3.16227912903
3.16227436066 3.16227912903 3.16227436066
3.16227674484 3.16227912903 3.16227674484
3.16227674484 3.16227793694 3.16227793694
3.16227734089 3.16227793694 3.16227734089
3.16227763891 3.16227793694 3.16227763891
3.16227763891 3.16227778792 3.16227778792
3.16227763891 3.16227771342 3.16227771342
3.16227763891 3.16227767617 3.16227767617
0.0 11.5 11.5
0.0 5.75 5.75
2.875 5.75 2.875
4.3125 5.75 4.3125
4.3125 5.03125 5.03125
4.671875 5.03125 4.671875
4.671875 4.8515625 4.8515625
4.76171875 4.8515625 4.76171875
4.76171875 4.806640625 4.806640625
4.7841796875 4.806640625 4.7841796875
4.79541015625 4.806640625 4.79541015625
4.79541015625 4.80102539062 4.80102539062
4.79541015625 4.79821777344 4.79821777344
4.79541015625 4.79681396484 4.79681396484
4.79541015625 4.79611206055 4.79611206055
4.7957611084 4.79611206055 4.7957611084
4.7957611084 4.79593658447 4.79593658447
4.7957611084 4.79584884644 4.79584884644
4.79580497742 4.79584884644 4.79580497742
4.79582691193 4.79584884644 4.79582691193
4.79582691193 4.79583787918 4.79583787918
4.79582691193 4.79583239555 4.79583239555
4.79582965374 4.79583239555 4.79582965374
4.79583102465 4.79583239555 4.79583102465
4.79583102465 4.7958317101 4.7958317101
4.79583136737 4.7958317101 4.79583136737
4.79583136737 4.79583153874 4.79583153874
4.79583145306 4.79583153874 4.79583145306
4.7958314959 4.79583153874 4.7958314959
0.0 12.5 12.5
0.0 6.25 6.25
3.125 6.25 3.125
4.6875 6.25 4.6875
4.6875 5.46875 5.46875
4.6875 5.078125 5.078125
4.8828125 5.078125 4.8828125
4.98046875 5.078125 4.98046875
4.98046875 5.029296875 5.029296875
4.98046875 5.0048828125 5.0048828125
4.99267578125 5.0048828125 4.99267578125
4.99877929688 5.0048828125 4.99877929688
4.99877929688 5.00183105469 5.00183105469
4.99877929688 5.00030517578 5.00030517578
4.99954223633 5.00030517578 4.99954223633
4.99992370605 5.00030517578 4.99992370605
4.99992370605 5.00011444092 5.00011444092
4.99992370605 5.00001907349 5.00001907349
4.99997138977 5.00001907349 4.99997138977
4.99999523163 5.00001907349 4.99999523163
4.99999523163 5.00000715256 5.00000715256
4.99999523163 5.00000119209 5.00000119209
4.99999821186 5.00000119209 4.99999821186
4.99999970198 5.00000119209 4.99999970198
4.99999970198 5.00000044703 5.00000044703
4.99999970198 5.00000007451 5.00000007451
4.99999988824 5.00000007451 4.99999988824
4.99999998137 5.00000007451 4.99999998137
4.99999998137 5.00000002794 5.00000002794
0.0 0.5 0.5
0.0 0.25 0.25
0.0 0.125 0.125
0.0 0.0625 0.0625
0.0 0.03125 0.03125
0.0 0.015625 0.015625
0.0 0.0078125 0.0078125
0.0 0.00390625 0.00390625
0.0 0.001953125 0.001953125
0.0 0.0009765625 0.0009765625
0.0 0.00048828125 0.00048828125
1.0 2 1.0
1.0 1.5 1.5
1.25 1.5 1.25
1.375 1.5 1.375
1.375 1.4375 1.4375
1.40625 1.4375 1.40625
1.40625 1.421875 1.421875
1.4140625 1.421875 1.4140625
1.4140625 1.41796875 1.41796875
1.4140625 1.416015625 1.416015625
1.4140625 1.4150390625 1.4150390625
1.4140625 1.41455078125 1.41455078125
1.4140625 1.41430664062 1.41430664062
1.41418457031 1.41430664062 1.41418457031
1.41418457031 1.41424560547 1.41424560547
1.41418457031 1.41421508789 1.41421508789
1.4141998291 1.41421508789 1.4141998291
1.4142074585 1.41421508789 1.4142074585
1.41421127319 1.41421508789 1.41421127319
1.41421318054 1.41421508789 1.41421318054
1.41421318054 1.41421413422 1.41421413422
1.41421318054 1.41421365738 1.41421365738
1.41421341896 1.41421365738 1.41421341896
0.5 1 0.5
0.5 0.75 0.75
0.625 0.75 0.625
0.6875 0.75 0.6875
0.6875 0.71875 0.71875
0.703125 0.71875 0.703125
0.703125 0.7109375 0.7109375
0.70703125 0.7109375 0.70703125
0.70703125 0.708984375 0.708984375
0.70703125 0.7080078125 0.7080078125
0.70703125 0.70751953125 0.70751953125
0.70703125 0.707275390625 0.707275390625
0.70703125 0.707153320312 0.707153320312
0.707092285156 0.707153320312 0.707092285156
0.707092285156 0.707122802734 0.707122802734
0.707092285156 0.707107543945 0.707107543945
0.707099914551 0.707107543945 0.707099914551
0.707103729248 0.707107543945 0.707103729248
0.707105636597 0.707107543945 0.707105636597
0.707106590271 0.707107543945 0.707106590271
0.707106590271 0.707107067108 0.707107067108
Pass

 

        牛顿法

          同样是求20的平方根,利用牛顿法求,迭代的次数要少。

 

#!/usr/bin/env python
# coding: utf-8
#copyRight by heibanke

def sqrt_func(x, small):
    #check input
    assert x>=0
    assert small>0, str(small)
    
    #init value
    loops = 1
    low = 0.0
    high = max(x,1)
    while True and loops<=100:
        guess = (low+high)/2
        #2fen
        if abs(guess**2-x)<small:
            break
        elif guess**2 < x:
            low = guess
        else:
            high = guess
                    
        #print low,high,guess
        loops+=1
        
    return guess,loops

def sqrt_nd(x,small):
    #check input
    assert x>=0
    assert small>0, str(small)
    
    #init value
    loops = 1
    low = 0.0
    high = max(x,1)
    guess = (low+high)/2
    while abs(guess**2-x)>small and loops<=100:
        guess = guess - (guess**2-x)/2/guess
        loops+=1
    return guess,loops
    
    
if __name__=="__main__":
    import math
    small_value = 0.0000001
    test_data = [10.0, 23, 25, 0, 2, 0.25, 0.5, 123456789,4]
    
    print u"二分法结果:"
    for x in test_data:
        y,loops=sqrt_func(x,small_value)
        assert abs(y**2-x)<small_value, u"二分法出错在"+str(x)
        print u"%d 次迭代的结果是 %f"%(loops,y)
        
        
    print u"
牛顿法结果:"        
    for x in test_data:
        y,loops=sqrt_nd(x,small_value)
        assert abs(y**2-x)<small_value, "牛顿法出错在"+str(x)  
        print u"%d 次迭代的结果是 %f"%(loops,y)        
    print "Pass"

    迭代次数比较:

                  

 

2、函数式编程

  函数式编程时一种编程方法。以前的编程方法都是结构式的,第一步、第二步、第三步……,而函数式编程把函数当做变量来组合。

 

  编程方法:

    不同语言的不同点:

      语法,运行环境和库的使用等

    不同语言的相同点:

      语言层面:编程方法和模式。

        哪些场景适合什么方法和模式?

      底层:数据结构和算法

        怎么存储最高效,怎么折腾数据最快。概率论,统计学,数学。

      高层:各种应用所需要的原理

        比如机器学习、网络,爬虫、信号处理

     Python里边一切皆对象,则函数也是一个对象。

    可直接赋给变量: my_sum=sum

    有属性和方法:__call__   (决定是否可以被调用)

            __name__  (其根本的名字)

      

 

      高阶函数:

        def f1(f,a,b)  把函数当参数的函数就可以叫做高阶函数

          pirnt f(a,b)

         

        如果式子发生变化,结构式编程还需要再写函数,而函数式编程不需要,只需把写好的进行组合一下就可以了。

 

        自带的高阶函数:

          filter     过滤,把字符串中只有数字或者数字的过滤出来

          

          map 映射,通过maplist里边都算一遍

          

 

          reduce  归纳演绎 

          

          求1+2+3……+100=

          统计单词词频

            很多文章,要统计他们的十大最热门词汇

              (1)文本处理,统计每个文章的词汇

              (2)合并不同文章的词汇

              (3)排序,输出

            github------------------wordsworth

          函数式编程——lambda

            用法:

              lower=(lambda x,y:x if x<y else y)

              lambda后边的xy是参数,冒号后边是返回值,如果x<y则返回x,否则返回y。返回值是一个函数。我们可以直接调用lower,如lower(2,3),返回的就是2

               

              为什么可以使用各种参数呢?因为Python是动态类型,都是对操作符的重载,如果是c++的话,要写各种操作符的重载函数。

              函数式编程:

                lst=random.randint(-50,50)

                lst2=filter(lamdba n:n>0,lst)

                lst3=map(lamdba x:x*2,lst)

                c=sorted(lst,cmp=lamdba x,y:x-y)

                sorted第一个参数是要排序的列表,第二个参数以前我们用的是关键字key,这次我们用一个函数表示,一般我们用lamdba函数,x-y如果返回的

                是一个正数,在sorted里边的意思是这个数尽量往后排。所以它是一个递增的。还有一个排序的方式是用list的一个函数——sort函数

                  lst.sort(lamdba x,y:1 if x>y else -1)

                  sort函数参数就是一个lamdba的函数。

                  

    

                  上边并没有完成我们预期的。说明讲课的老师这个地方讲错了,如果要实现想要的结果,应该这样写:

                  

                  然后用join()进行输出,join()函数的意思是

                  join()函数

                  语法:  'sep'.join(seq)

                  参数说明
                    sep:分隔符。可以为空
                    seq:要连接的元素序列、字符串、元组、字典
                    上面的语法即:以sep作为分隔符,将seq所有的元素合并成一个新的字符串

                    返回值:返回一个以分隔符sep连接各个元素后生成的字符串

  函数式编程——函数返回

    内部函数:

      def calc2(s):

        def f_add(a,b):return a+b

        def f_mul(a,b):return a*b

        def f_sub(a,b):return a-b

 

        if s==’+’:

          return f_add

        elif s==’*’:

          return f_mul

        elif s==’-’:

          return f_sub

        else:

          assert False, ’error’

    内部函数无法被外部调用的。

    上边的程序可以改成lambda的形式,因为内部函数我无需知道具体的函数名字,而是直接返回一个值就可以了。

 

      def calc2(s):

        if s=='+':

          return lambda a,b:a+b

           elif s=='*':

                return lambda a,b:a*b

           elif s=='-':

          return lambda a,b:a-b

        else :

          assert False,'error:operator not defined'

 

        如果还想再简单点,可以用字典这么写:

          calc_dict={

            ‘+’:lambda a,b:a+b,

            ‘*’:lambda a,b:a*b,

            ‘-’:lambda a,b:a-b,

          }

          调用的时候:calc_dict[‘+’](1,2)

    函数式编程——就是把函数当做数据进行处理。

3、回调

  在cc++中回调函数一般用的是函数指针。

  函数作为参数,调用完之后还回来。

    def test (calback):

      print’test func begin’

      callback()

      print’test func end’

 

 

    def cb1():

      print’callback 1’

    def cb2():

      print’callback 2’

    test(cb1)

    test(cb2)

    经常用的地方:按钮的地方用回调函数。

4、闭包和装饰器——函数作为返回值

  闭包closure:

    绑定外部变量——让它自己维护自己的信息

    def pow_x(x):

      def echo(value):

        return value**x

      return echo

      返回的是echo这个函数

 

    lst=[pow_x(2),pow_x(3),pow_x(4)]  这里的2,3,4是参数x的值

    for p in lst:

      print p(2)   这里的2是参数value的值

      

    什么是闭包:已经绑定了外部变量的内部函数

      上边的lst里边都是闭包。

    特点:

      1、嵌套函数

      2、内部函数用到了外部变量(通常是外部函数的参数)

      3、外部函数返回内部函数

 

      

 

      如果在里边把x的值改为2,则它永远都是2次方。

 

 

  内部函数:

 

    1、内部函数不能‘改变’外部变量,即不能产生一个和外部变量一样的东西。即局部变量和外部变量是两个变量,不干涉。

    2、内部函数用到了外部变量为list或其他可变的,则可以从外部或内部改变值,并且是外部没有引用也不会回收。

    举例:

      def pow_y(x):

        def echo(value):

          #x[0]=x[0]*2如果不注释,意思是先访问x[0],然后在赋给值,这不会产生局部变量,依然是一个外部变量。只是对外部变量修改了。

          #x=[2,2] 如果不注释,意思是生成了一个局部变量。

          return value**x[0]value**x[1]

        return echo

        

 

      origin=[0,0]#坐标系统原点

      legal_x=[0,50] #x轴的合法坐标

      legal_y=[0,50] #y轴的合法坐标

 

      def create(pos):

          def player(direction ,step):

              #这里应该判断dirctionstep的合法性

              #然后还要对新生成的x,y的合法性做判断

              new_x=pos[0]+direction[0]+step

              new_y=pos[1]+direction[1]+step

              pos[0]=new_x

              pos[1]=new_y

              return pos

          return player

 

      player1=create(origin[:])

      #创建棋子1

      print player1([1,0],10)#x轴方向移动10

      print player1([0,1],20)#y轴方向移动20

      print player1([-1,0],10)#y轴负方向移动10

 

      print 'origin is ',origin

 

      player2=create(origin[:])

      #创建棋子2

      print player2([-1,0],10)

      print player2([1,1],20)

      print player2([1,0],10)

      这是闭包的一个应用,每个player各自维护自己的数据。

  装饰器——无嵌套

    装饰:在原有函数的基础上加一些功能。函数作为返回值,函数作为参数的一种应用。和设计模式里边的装饰器有些类似。

    举例:

      def decorator(f):

          print 'before'+ f.__name__+ 'called'

          return f

 

      def myfunc1():

          print 'myfunc1() called'

      #显示说decorator是一个装饰器,把myfunc2()装饰一下

      @decorator  

      def myfunc2():

          print 'myfunc2 called'

      if __name__=='__main__':

          pass

          decorator(myfunc1)()

          myfunc2()

       上边这两句语句一样的作用。

      

      从运行结果上看,beformyfunc2called 先输出的,为什么?

      因为用了@decorator之后,导入的时候就会被运行。

 

 

      三个问题:

        1@装饰器会提前执行

        2目标函数无法带参数

        3、目标函数调用后无法插入代码

 

    装饰器——2层嵌套

      函数带参数

        def time_cost(f):

          def _f(*arg,**kwarg):

            start=time.clock()

            f(*arg,**kwarg)

            end=time.clock()

            print end-start

          return _f

        @time_cost

        def list_comp(length):

          return [(x,y) for x in range(length) for y in range(length) if x*y>25]

          问题1,装饰被提前执行也不会输出值,因为返回的是一个内部的函数,而这个函数并没有被执行,所以问题1解决了。

          问题2,实际上目标函数已经带了参数,所以,问题2解决了

          问题3,想插入多少代码就可以插入多少代码

           

 

          这里用的是一个参数的。

          

            这个用的多参数的。从上边的两个例子看出,我们直接运行的时候看不出来是用了装饰器的,只有看源码的时候才发现原来是用来装饰器。这里装饰器的

            作用是输出执行时间。而且是用了两层嵌套,所以即使提前执行,也不会输出结果。

            虽然两层结构实现了我们的需求,但是现在又有了一个问题:

            4、装饰器无法带参数

            加入我们现在有需求,希望求出最好的运行时间和平均运行时间,这个代码应该加在那里?应该加在装饰器上。

          装饰器——三层嵌套

            装饰器带参数:

              当我们会写两层的装饰器之后,再包装一层,然后返回就可以了。

            

import time
import random


def time_cost(timef):
    def decorator(f):
        def _f(*arg,**kwarg):
            #可以有多个参数
            start=time.clock()
            a=f(*arg,**kwarg)
            end=time.clock()
            print f.__name__,'run cost time is',end-start
            return a
        return _f
    return decorator

@time_cost(time.clock)
def list_comp(length):
    return [(x,y)for x in range(length) for y in range(length) if x*y>25]

@time_cost(time.clock)
def for_loop(length):
    a=[]
    for x in range(0,length):
        for y in range(0,length):
            if x*y>25:
                a.append((x,y))
    return a

if __name__=='__main__':
    
    a=list_comp(1000)
    print len(a)
    b=for_loop(1000)
    print len(b)
    

            

            装饰器的参数是在@后边的函数中带着。

            闭包就是这样被映射成装饰器的。

 

 

        装饰器——装饰模式

          设计模式:

          给小明穿衣服

 

          工作时穿工作服,西装,皮鞋,裤子

          运动时穿运动服,T恤,运动鞋,裤子,帽子

 

          把这种搭配做成套装可以直接给另一个人小红穿上

 

          这种套装还可以根据日期随意更换,比如周1-4穿工作服,但周2的工作服不穿西装穿T恤。周5-7穿运动装,但周五不戴帽子。

          下面实现部分功能

#coding:utf-8

def printInfo(info):
    print unicode(info,'utf-8')

def wearTrouser(f):
    def _f(*arg,**kwarg):
        printInfo('裤子')
        return f(*arg,**kwarg)
    return _f

def wearSuit(f):
    def _f(*arg,**kwarg):
        printInfo('西服')
        return f(*arg,**kwarg)
    return _f

def wearTShirt(f):
    def _f(*arg,**kwarg):
        printInfo('T恤')
        return f(*arg,**kwarg)
    return _f

def wearCap(f):
    def _f(*arg,**kwarg):
        printInfo('帽子')
        return f(*arg,**kwarg)
    return _f

def wearSportShoes(f):
    def _f(*arg,**kwarg):
        printInfo('运动鞋')
        return f(*arg,**kwarg)
    return _f

def wearLeatherShoes(f):
    def _f(*arg,**kwarg):
        printInfo('皮鞋')
        return f(*arg,**kwarg)
    return _f

#不断的给他穿衣服
def wearedPerson(person,cloths):
    w=person
    #理解此处的代码去看闭包
    for f in cloths:
        w=f(w)
    return w


#@wearTrouser
#@wearTShirt
#加上装饰器之后,他就穿上裤子和T恤了
def person (name):
    printInfo('装扮好的%s' %name)


person('小明')
print"---------------------"
#商务套装
business_wear=[wearLeatherShoes,wearSuit,wearTrouser]
#运动套装
sports_wear=[wearSportShoes,wearCap,wearTShirt,wearTrouser]
weared_business_person=wearedPerson(person,business_wear)
weared_sport_person=wearedPerson(person,sports_wear)
weared_business_person('小明')
print '-------------------'
weared_sport_person('小红')

          

          装饰器这个地方理解起来需要时间,应该多看看。

5、递归

  函数调用自己

    裴波那契数列(兔子生兔子的问题)

    

    字符串取反(可以不用递归,这里用递归的方式演示):

    

    二分法也是一个递归调用的例子

def sqrt_func_dg(x,small,low,high):
    guess = float(low+high)/2

    if abs(guess**2-x)<small:
        return guess
    elif guess**2<x:
        return sqrt_func_dg(x,small,guess,high)
    else:
        return sqrt_func_dg(x,small,low,guess)

    递归——编程方法

      快速排序

      具体的可以参考数据结构的辅导书,此处不再赘述。

 

6、生成器和yield

  Iterable,Iterator,Generator

  可迭代的,迭代器,生成器

  其中,迭代器是可迭代的一个子集。

  什么是可迭代的?

  凡是可以写到for循环后边的都是可迭代的。如字典、列表等。

  什么是生成器?

  生成器是生成一个迭代器的东西。

  迭代器是一个对象,生成器是一个函数或表达式。

  如何把函数变成一个生成器,就是通过yield语句。

  如何把表达式变成一个生成器,元组的推导式解析式。

  next的用法:

    还是用斐波那契的例子。因为上一次我们用的是迭代,所以实际运行时间会长。

    

      包含yield语句的函数会被特地编译成生成器。当函数被调用时,他们返回一个生成器对象,这个对象支持迭代器接口

      这是Python里边的惰性计算,只有用到的时候才算出来值,不用的不是后不计算。而且前边就算出来的值都被保存下来了。可以继续利用。

      xrange函数与range函数的区别:

      1range()返回的是整个list

      2xrange()返回的是一个xrange object,且这个对象是一个iterable.

      3、两者都是for循环

      4xrange()占用更少的内存空间,因为循环时xrange()只生成当前的元素,不像range()一开始就生成完整的list

      运行时间的比较:

      

 

      

      下边的形式是错误的,需要注意:

 

      

      

      这样写,那个函数实际上每次都是从新调用。所以输出结果都是1

      迭代器,当往后算的时候,1-------100这个方向前进的时候是可以用迭代器进行计算,前边的它会保存下,而100--------1这个方向前进的时候,迭代器就用不上了。

      send用法:

 

def func():
    input=[]
    while True:
        a=(yield)
        your statement
        input.append(a)    

 

    好处:生成器自己维护环境变量。

    相对于next,send用的还是比较少一些。

 

 

    一个带有 yield 的函数就是一个 generator,它和普通函数不同,生成一个 generator 看起来像函数调用,但不会执行任何函数代码,直到对其调用 next()(在 for 循环中会

    自动调用next())才开始执行。虽然执行流程仍按函数的流程执行,但每执行到一个 yield 语句就会中断,并返回一个迭代值,下次执行时从 yield 的下一个语句继续执行。

    看起来就好像一个函数在正常执行的过程中被 yield 中断了数次,每次中断都会通过 yield 返回当前的迭代值。

 

    yield 的好处是显而易见的,把一个函数改写为一个 generator 就获得了迭代能力,比起用类的实例保存状态来计算下一个 next() 的值,不仅代码简洁,而且执行流程异常清

    晰。

 

 

    推断:迭代器就是应该返回给一个变量来接收,这就成了迭代器。

 

    关于yield的具体理解还需网上资源查找学习,比如这篇:

    http://www.ibm.com/developerworks/cn/opensource/os-cn-python-yield/

 

 

    我们看一下库里还有哪些迭代器:

      itertools

        horses=[1,2,3,4]

        races=itertools.permutations(horses)

        #itertools返回的结果是一个迭代器,这个迭代器会把1,2,3,4的所有组合求出来。举个例子,当你需要穷举的时候。

 

        A=itertool.product([1,2],[3,4])

        product返回的是一个迭代器,这个迭代器有两个列表,也将会求出所有的组合,如1,3 1,4 2,3 2,4

        B=itertool.repeat([1,2],4)

        重复多少遍。

 

        C=itertools.chain(races,a,b)

        把这几个迭代器链起来。

 

        

原文地址:https://www.cnblogs.com/shixisheng/p/5919457.html