zoukankan      html  css  js  c++  java
  • 流畅的python学习笔记:第五章

    在python中一切都可以视作为对象,包括函数。我们来看个例子:
    def function_try():
        '''it is funciton try doc'''
       
    print 'function_try'
    if
    __name__=="__main__":
        print function_try.__doc__
        print function_try.__name__
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    it is funciton try doc
    function_try
    在这里__doc__输出了函数function_try在开头的帮助。__name__则是输出了具体的函数名
    我们还可以将函数名赋值给变量。通过变量的形式来访问
    def function_try():
        '''it is funciton try doc'''
       
    print 'function_try_print'
    if
    __name__=="__main__":
        fun=function_try
        print fun.__doc__
        print fun.__name__
        fun()
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    it is funciton try doc
    function_try
    function_try_print
     
    函数也可以通过参数被传递给另外一个函数。
    def function_try():
        '''it is funciton try doc'''
       
    print 'function_try_print'

    def
    function_try1(fun):
        print fun.__doc__
        print fun.__name__
        fun()

    if __name__=="__main__":
        f=function_try
        function_try1(f)
     
    下面来介绍下函数的高级用法。
    假设有一字符列表,想通过各个字符的长度来进行排序。我们首先想到的是下面的方法。用sort的方法,并在key中指明排序的依据。在这里用到了lambda来得到每个元素的长度。
    fruits=['strawberry','fig','apple','cherry','rasberry','banana']
    fruits.sort(key=lambda x:len(x))
    print fruits
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    ['fig', 'apple', 'cherry', 'banana', 'rasberry', 'strawberry']
    还可以直接用sorted的方法。不同的是sorted是另外返回一个排序后的列表,原列表fruits并没有发生改变
    fruits=['strawberry','fig','apple','cherry','rasberry','banana']
    ret=sorted(fruits,key=len)
    print 'after sorted %s' % ret
    print 'before sorted %s' % fruits
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    after sorted ['fig', 'apple', 'cherry', 'banana', 'rasberry', 'strawberry']
    before sorted ['strawberry', 'fig', 'apple', 'cherry', 'rasberry', 'banana']
     
    下面来介绍几个高阶函数:map,filter,reduce
    首先来看下map的定义:

    map(functioniterable...)

    Apply function to every item of iterable and return a list of the results. If additional iterable arguments are passed,function must take that many arguments and is applied to the items from all iterables in parallel. If one iterable is shorter than another it is assumed to be extended withNoneitems. If function isNone, the identity function is assumed; if there are multiple arguments, map() returns a list consisting of tuples containing the corresponding items from all iterables (a kind of transpose operation). The iterable arguments may be a sequence or any iterable object; the result is always a list.

    简单归纳就是对于可迭代对象iterable中的每一个元素应用function方法。并将结果做为list返回
    来看下例子:
    def add_num(n):
        return n+1

    if __name__=="__main__":
        print map(add_num,range(1,6))
    range(1,6)中的各个元素都被add_num调用然后生成一个列表。其实效果相当于[add_num(n) for n in range(1,6)].因此map可以看做是一个列表推导式
    我们再来另外一个应用
    def add_num(a,b,c):
        return a+b+c

    if __name__=="__main__":
        print map(add_num,range(1,6),range(7,12),range(11,16))
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    [19, 22, 25, 28, 31]
    这个写法的作用是将3个range中的元素按照顺序依次想加。这样写是不是比逐个遍历要方便很多。
    再来看下filter。
    s=[1,2,3,4,5]
    print filter(lambda x:x>3,s)
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    [4, 5]
    Filter的作用在于根据第一个参数为true还是false来进行过滤。上面例子中将大于3的数值过滤出来。
     
    下面介绍下reduce的作用。我们先来看下说明:
    Apply a function of two arguments cumulatively to the items of a sequence,
    from left to right, so as to reduce the sequence to a single value.
    For example, reduce(lambda x, y: x+y, [1, 2, 3, 4, 5]) calculates
    ((((1+2)+3)+4)+5).  If initial is present, it is placed before the items
    of the sequence in the calculation, and serves as a default when the
    sequence is empty.
    上面的说明很形象了,就是将参数累加的应用于函数中。就好比我们要对1到100进行求值。代码如下。效果等同于sum(range(100))
    from operator import add
    print reduce(add,range(100))
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    4950
    对于reduce请注意这句话:Apply a function of two arguments cumulatively to the items of a sequence,意思是传入的函数必须接受2个参数。意味着传输的计算源必须至少是有2个。
     
    前面介绍到可以把函数当做对象。那么我们可以像调用函数那样调用类么。答案是肯定的。只需要我们重写类中的__call__就可以了
    class function_try:
        def __init__(self,value):
            self.data=value
        def __call__(self, *args, **kwargs):
            print 'function try was called'
            for
    a in args:
                print a

    if __name__=="__main__":
        f=function_try(3)
        print f(3,2)
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    function try was called
    3
    2
    当我们用print f(3,2).起作用的其实是__call__方法。
    除了__doc__, __name__这些函数还有很多属性。可以用dir的方法进行查看
    def add_num(a,b,c):
        return a+b+c
    print dir(add_num)
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    ['__call__', '__class__', '__closure__', '__code__', '__defaults__', '__delattr__', '__dict__', '__doc__', '__format__', '__get__', '__getattribute__', '__globals__', '__hash__', '__init__', '__module__', '__name__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'func_closure', 'func_code', 'func_defaults', 'func_dict', 'func_doc', 'func_globals', 'func_name']
    可以看到上面这么多的方法。类中也有很多的属性,哪些是函数特有的呢。可以写一个空类和空的函数来进行对比
    class c:
        pass

    def
    func():
        pass
    if
    __name__=="__main__":
        print sorted(set(dir(func))-set(dir(c)))
     
    函数参数的获取:首先来看下面的代码
     
    def func_argument(text,length=10):
        if len(text) > length:
            ret='override'
        else
    :
            ret=text[0:length]
        return ret
    if __name__=="__main__":
        print func_argument.__defaults__
        print func_argument.__code__
        print func_argument.__code__.co_varnames
        print func_argument.__code__.co_argcount
    运行结果:
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    (10,)
    <code object func_argument at 01875188, file "E:/py_prj/fluent_python/chapter5.py", line 36>
    ('text', 'length', 'ret')
    2
     
    __defaults__输出的是参数的默认值,这里length被初始化为10
    __code__.co_varnames输出的是具体的参数名称。从结果可以看到输出有text,length,ret。不光是有传入的参数,还有内部定义的参数
    __code__.co_argcount 代表的是函数传入参数的个数。通过__code__.co_argcount就可以知道在__code__.co_varnames哪些是函数传入的参数,哪些是函数内部定义的参数。
     
    在前面曾经讲到过sorted的方法以及lambda的用法。这里再介绍一个高级点的用法:有一个列表,里面存储了各个城市的信息。我们想根据国家代码(第二个字段)的顺序打印各个城市的信息。大家第一反应肯定是用sorted,然后key值用lambda来表示:
    metro_data=[('tokyo','jp','36.933',(35.689722,139.691667)),('Delhi NCR','IN',21.935,(28.613889,77.208889)),('Mexico city','MX',20.142,(19.43333,-99.13333))]
    x=sorted(metro_data,key=lambda x:x[1])
    其实我们可以用一个更简洁的方法:itemgetter
    metro_data=[('tokyo','jp','36.933',(35.689722,139.691667)),('Delhi NCR','IN',21.935,(28.613889,77.208889)),('Mexico city','MX',20.142,(19.43333,-99.13333))]
    for city in sorted(metro_data,key=itemgetter(1)):
        print city
    通过代码比较其实可以发现itemgetter其实就和lambda x:x[1]的作用是一样的。
     
    最后介绍一个可以冻结参数的功能。Functions.partial. 在某些场景下,我们期望可以冻结一个参数,并将这个参数作用于其他参数。代码如下:
    from functools import partial
    from operator import mul
     
    triple=partial(mul,3)  #将第一个参数固定为3
    print triple(7)    #=7*3
    print list(map(triple,range(1,10))) #1,10分别和3相乘
     
    E:python2.7.11python.exe E:/py_prj/fluent_python/chapter5.py
    21
    [3, 6, 9, 12, 15, 18, 21, 24, 27]
  • 相关阅读:
    【简单算法】27.验证二叉搜索树
    【简单算法】26. 二叉树的最大深度
    【简单算法】25. 环形链表
    pandas 数据处理
    主成分分析 PCA
    hive 导出数据到本地
    深度学习的优化方法 总结
    ALS算法 (面试准备)
    Bagging和Boosting的区别(面试准备)
    ROC 曲线,以及AUC计算方式
  • 原文地址:https://www.cnblogs.com/zhanghongfeng/p/7071711.html
Copyright © 2011-2022 走看看