您的位置:首页 > 编程语言 > Python开发

python基础-特性

2015-10-27 16:09 204 查看
导航:

  高阶特性:

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

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

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

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

[b]  高阶函数:[/b] 

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

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

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

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

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

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

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

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

    [b]偏函数:[/b]
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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: