• python基础-特性


    导航:

      高阶特性:

        切片:Python没有针对字符串的截取函数,只需要切片一个操作就可以完成

        迭代:Python的for循环抽象程度要高于Java的for循环,因为Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上

        列表生成器:即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式

        生成器:Generator,一系列算法,使用时才计算值,一般采用for遍历.关键字yield

      高阶函数: 

        map: map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

        reduce: reduce() 函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算。

        filter: filter()也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素。

        sorted: Python内置的sorted()函数就可以对list进行排序.

        返回函数:函数作为返回值,闭包

        匿名函数:不需要显式地定义函数,直接传入匿名函数,关键字lambda表示匿名函数,冒号前面的值表示函数参数.

        函数参数:必选参数、默认参数、可变参数和关键字参数.

        装饰器:增强函数的功能,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator

        偏函数functools.partial,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单

        

     ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

    高阶特性:

      切片:Python没有针对字符串的截取函数,只需要切片一个操作就可以完成,非常简单。

        L[a:b] , 获取下标a至下标(b-1)之间的元素,如果a为0还可以省略,例如:L[:3]

        L[-a:-b],获取倒数第a个元素至倒数第b个元素之间的元素,如果-b 为-1 还可以省略,例如:[-10:]

        L[a:b:c],获取下标a至下标(b-1)之间的元素,并且每隔c个元素取得一个元素,如果a和b是负数,同上,c不能为负数,否则返回空集.

        L[::c],每隔c个元素取一个元素,且c不能为负数.

      迭代: Python的for循环抽象程度要高于Java的for循环,因为Python的for循环不仅可以用在list或tuple上,还可以作用在其他可迭代对象上。

        迭代是通过for ... in来完成

        只要是可迭代对象,无论有无下标,都可以迭代,比如字符串:

    >>> for ch in 'ABC':
    ...     print ch
    ...
    A
    B
    C

        只要作用于一个可迭代对象,for循环就可以正常运行,判断一个对象是可迭代对象:

    >>> from collections import Iterable
    >>> isinstance('abc', Iterable) # str是否可迭代
    True
    >>> isinstance([1,2,3], Iterable) # list是否可迭代
    True
    >>> isinstance(123, Iterable) # 整数是否可迭代
    False

        Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

    >>> for i, value in enumerate(['A', 'B', 'C']):
    ...     print i, value
    ...
    0 A
    1 B
    2 C

        for循环里,同时引用了多个变量,在Python里是很常见的,比如下面的代码:

    >>> for x,y,z in [(1,1,2),(2,4,6),(3,9,12)]:
    ...         print x,y,z
    ...
    1 1 2
    2 4 6
    3 9 12

        dict迭代的是key。如果要迭代value,可以用for value in d.itervalues(),如果要同时迭代key和value,可以用for k, v in d.iteritems()

      列表生成器:

        即List Comprehensions,是Python内置的非常简单却强大的可以用来创建list的生成式:

    >>> [str(x)+'*'+str(x) for x in range(1,11)]
    ['1*1', '2*2', '3*3', '4*4', '5*5', '6*6', '7*7', '8*8', '9*9', '10*10']
    >>> [x * x for x in range(1,11)]
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    >>> [x * x for x in range(1,11) if x % 2 == 0]
    [4, 16, 36, 64, 100]
    >>> [m + n for m in 'ABC' for n in 'XYZ']
    ['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
    >>> import os # 导入os模块,模块的概念后面讲到
    >>> [d for d in os.listdir('.')] # os.listdir可以列出文件和目录
    ['.emacs.d', '.ssh', '.Trash', 'Adlm', 'Applications', 'Desktop', 'Documents', 'Downloads', 'Library', 'Movies', 'Music', 'Pictures', 'Public', 'VirtualBox VMs', 'Workspace', 'XCode']
    >>> d = {'a':'A','u':'B','z':'C'}
    >>> [ k + '=' + v for k,v in d.iteritems()]
    ['a=A', 'z=C', 'u=B']
    >>> L = ['Hello','World','IBM','Apple']
    >>> [s.lower() for s in L]
    ['hello', 'world', 'ibm', 'apple']

         list中既包含字符串,又包含整数,由于非字符串类型没有lower()方法:

    >>> L = ['Hello','World',18,'Apple',None]
    >>> [s.lower() for s in L if isinstance(s,str)]
    ['hello', 'world', 'apple']

      生成器:列表元素按照某种算法推算出来,可以在循环的过程中不断推算出后续的元素,这样就不必创建完整的list,从而节省大量的空间。在Python中,这种一边循环一边计算的机制,称为生成器Generator)

        创建一个generator,有很多种方法:

        1、把一个列表生成式的[]改成(),就创建了一个generator

    >>> L = [ x * x for x in range(10)]
    >>> L
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
    >>> g=(x * x for x in range(10))
    >>> g
    <generator object <genexpr> at 0x0250DEB8>

        打印出generator的每一个元素,如果要一个一个打印出来,可以通过generator的next()方法

    >>> g.next()
    0
    >>> g.next()
    1
    >>> g.next()
    4

        也可以采用遍历的方式:

    >>> from collections import Iterable
    >>> isinstance(g,Iterable)
    True
    >>> [ j for j in g]
    [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

       generator非常强大。如果推算的算法比较复杂,用类似列表生成式的for循环无法实现的时候,还可以用函数来实现。

      比如,著名的斐波拉契数列(Fibonacci),除第一个和第二个数外,任意一个数都可由前两个数相加得到:

      1, 1, 2, 3, 5, 8, 13, 21, 34, ...

    def fib(max):
        n, a, b = 0, 0, 1
        while n < max:
            yield b
            a, b = b, a + b
            n = n + 1

      2、如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator:

    >>> def fib(max):
    ...   n,a,b = 0,0,1
    ...   while n < max:
    ...     yield b
    ...     a,b = b, a + b
    ...     n = n + 1
    ...
    >>> fib(6)
    <generator object fib at 0x024FC328>

      最难理解的就是generator和函数的执行流程不一样。函数是顺序执行,遇到return语句或者最后一行函数语句就返回。而变成generator的函数,在每次调用next()的时候执行,遇到yield语句返回,再次执行时从上次返回的yield语句处继续执行。

    高阶函数:就是让函数的参数能够接收别的函数。

      map:

        map()函数接收两个参数,一个是函数,一个是序列,map将传入的函数依次作用到序列的每个元素,并把结果作为新的list返回。

      reduce:

         reduce把一个函数作用在一个序列[x1, x2, x3...]上,这个函数必须接收两个参数,reduce把结果继续和序列的下一个元素做累积计算,其效果就是:

    reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4)

      更多python内建函数:https://docs.python.org/2/library/functions.html 

      filter:

        filter()也接收一个函数和一个序列。和map()不同的时,filter()把传入的函数依次作用于每个元素,然后根据返回值是True还是False决定保留还是丢弃该元素

    >>> def is_odd(n):
    ...   return n %2 ==1
    ...
    >>> filter(is_odd,[1,2,4,5,6,8,9])
    [1, 5, 9]
    >>> def not_empty(s):
    ...   return s and s.strip()
    ...
    >>> filter(not_empty,['A','','B',None,'C',' '])
    ['A', 'B', 'C']

        练习:filter()删除1~100的素数 以及 filter()删除1~100的非素数:

    #判断是不是素数/质数
    def
    is_primes(n): for i in range(2,n): if n % i == 0: return False; return True;
    #判断不是素数/质数
    def not_primes(n): for i in range(2,n): if n % i == 0: return True return False; if __name__ == '__main__': notp = filter(not_primes,range(2,101)) #100以内不是素数/质数的 isp = filter(is_primes,range(2,101)) #100以内是素数/质数的 print notp print isp

    [4, 6, 8, 9, 10, 12, 14, 15, 16, 18, 20, 21, 22, 24, 25, 26, 27, 28, 30, 32, 33, 34, 35, 36, 38, 39, 40, 42, 44, 45, 46, 48, 49, 50, 51, 52, 54, 55, 56, 57, 58, 60, 62, 63, 64, 65, 66, 68, 69, 70, 72, 74, 75, 76, 77, 78, 80, 81, 82, 84, 85, 86, 87, 88, 90, 91, 92, 93, 94, 95, 96, 98, 99, 100]
    [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]

      sorted:

        Python内置的sorted()函数就可以对list进行排序:

    >>> sorted([36, 5, 12, 9, 21])
    [5, 9, 12, 21, 36]

        sorted()函数也是一个高阶函数,它还可以接收一个比较函数来实现自定义的排序。比如,如果要倒序排序,我们就可以自定义一个reversed_cmp函数:

    def reversed_cmp(x, y):
        if x > y:
            return -1
        if x < y:
            return 1
        return 0
    >>> sorted([36, 5, 12, 9, 21], reversed_cmp)
    [36, 21, 12, 9, 5]
    >>> sorted(['bob', 'about', 'Zoo', 'Credit'])
    ['Credit', 'Zoo', 'about', 'bob']
    def cmp_ignore_case(s1, s2):
        u1 = s1.upper()
        u2 = s2.upper()
        if u1 < u2:
            return -1
        if u1 > u2:
            return 1
        return 0
    >>> sorted(['bob', 'about', 'Zoo', 'Credit'], cmp_ignore_case)
    ['about', 'bob', 'Credit', 'Zoo']

       返回函数:函数作为返回值,闭包

    def lazy_sum(*args):
        def sum():
            ax = 0
            for n in args:
                ax = ax + n
            return ax
        return sum

        调用函数返回的函数时,才真正计算求和的结果:

    >>> f = lazy_sum(1, 3, 5, 7, 9)
    >>> f
    <function sum at 0x10452f668>
    >>> f()
    25

        每次调用都会返回一个新的函数,即使传入相同的参数:

    >>> f1 = lazy_sum(1, 3, 5, 7, 9)
    >>> f2 = lazy_sum(1, 3, 5, 7, 9)
    >>> f1==f2
    False

      匿名函数:不需要显式地定义函数,直接传入匿名函数

    >>> map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9])
    [1, 4, 9, 16, 25, 36, 49, 64, 81]

      关键字lambda表示匿名函数,冒号前面的x表示函数参数

    >>> f = lambda x: x * x
    >>> f
    <function <lambda> at 0x10453d7d0>
    >>> f(5)
    25
    def build(x, y):
        return lambda: x * x + y * y

      函数参数:必选参数、默认参数、可变参数和关键字参数,

        必选参数:必须传入的参数,如:def func(a,b)

        默认参数:不必传入的有默认值得参数,如:def func(a,b=None), 注意默认参数必须指向不变对象,如 str,None

        可变参数:传入的参数个数是可变的,如:def func(*a),接受为一个tuple的不可变对象,如func(1,2,3) 在内部就是一个tuple的(1,2,3)

        关键字参数:键字参数允许你传入0个或任意个含参数名的参数,这些关键字参数在函数内部自动组装为一个dict。如 def func(**kv) , 接受一个为一个dict对象, 如 func(city='BeiJing') 接收为:{'city':'BeiJing'}

      装饰器:增强函数的功能,但又不希望修改now()函数的定义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)

    def log(func):
        def wrapper(*args, **kw):
            print 'call %s():' % func.__name__
            return func(*args, **kw)
        return wrapper

         借助Python的@语法,把decorator置于函数的定义处:

    >>> @log
    ... def now():
    ...   print '2015-10-27'
    ...
    >>> now()
    call now():
    2015-10-27

        如果decorator本身需要传入参数,那就需要编写一个返回decorator的高阶函数,写出来会更复杂。比如,要自定义log的文本:

    >>> def log(text):
    ...   def decorator(func):
    ...     def wrapper(*args,**kw):
    ...       print '%s %s:' %(text,func.__name__)
    ...       return func(*args,**kw)
    ...     return wrapper
    ...   return decorator
    ...
    >>> @log('execute')
    ... def now():
    ...   print '2013-12-25'
    ...
    >>> now()
    execute now:
    2013-12-25

          functools的wrap,它能保留原有函数的名称和docstring:

    #不带参数
    import
    functools def log(func): @functools.wraps(func) def wrapper(*args, **kw): print 'call %s():' % func.__name__ return func(*args, **kw) return wrapper
    #带参数
    import
    functools def log(text): def decorator(func): @functools.wraps(func) def wrapper(*args, **kw): print '%s %s():' % (text, func.__name__) return func(*args, **kw) return wrapper return decorator

        请编写一个decorator,能在函数调用的前后打印出'begin call''end call'的日志。

        再思考一下能否写出一个@log的decorator,使它既支持:

    import functools
    
    def log(*a):
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args, **kw):
                print 'begin call'
                if a is not None:
                    print 'log parameter: ',a
                res = func(*args,**kw)
                print 'end call'
                return res              #这里返回的值为None,因为执行的函数什么也没有返回.
            return wrapper
        return decorator
    
    @log()
    def decorator_test():
        print 'this is a decorator test function'
    
    if __name__ == '__main__':
        decorator_test()

      偏函数functools.partial,把一个函数的某些参数给固定住(也就是设置默认值),返回一个新的函数,调用这个新函数会更简单:

        将int()中的base参数固定住:

    >>> int('12345', base=8)
    5349
    >>> int('12345', 16)
    74565
    >>> int('12345')
    12345
    >>> int('12345',10)
    12345
    >>> import functools
    >>> int2 = functools.partial(int,base=2)
    >>> int2('10010')
    18

        http://www.liaoxuefeng.com/wiki/001374738125095c955c1e6d8bb493182103fac9270762a000/001386819893624a7edc0e3e3df4d5d852a352b037c93ec000

  • 相关阅读:
    linux 学习(二)防火墙
    linux学习(一)开始
    ajax和sap以及网络安全
    仿苹果导航菜单js问题
    基本类型和引用类型调用是的区别(Object.create)
    箴言
    思维的宽度
    笔记
    循环传值_闭包
    一个问题的解法(兔子三个月之后每月都生兔子的问题)
  • 原文地址:https://www.cnblogs.com/xccnblogs/p/4910849.html
Copyright © 2020-2023  润新知