python基础-特性

让人想犯罪 __ 提交于 2020-02-12 12:54:59

导航:

  高阶特性:

    切片: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 63 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

 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!