python学习零碎记三

xiaoxiao2021-02-28  144

本文是廖雪峰教程学习记录,廖雪峰链接:http://blog.csdn.NET/GarfieldEr007/article/details/52422494?locationNum=1&fps=1

切片、迭代、enumerate、collections.Iterable、isinstance、列表生成式、生成器generator、map()、reduce()、lambda函数、join、filter、strip、修饰器decorator、偏函数functools.partial

①切片

取list中的元素:L[a:b:c],索引a开始的b个元素中,每c个取一个

>>> L=['A','B','C','D','E']

>>> L[0:3] ['A', 'B', 'C'] #取索引0开始,索引3前的元素

>>> L[-3:-1] ['C', 'D'] #取索引-3开始,索引-1前的元素

>>> L[-2:] #索引-2以后的元素 ['D', 'E']

>>> L=range(100)

>>> L[:10:2] #前10个数,每两个取一个 [0, 2, 4, 6, 8]

>>> (1, 2, 3, 4, 5)[2:5]#tuple (3, 4, 5) >>> 'ABCDEFG'[2:5] #string 'CDE'

>>> u'ABCDEFG'[2:5]#Unicode u'CDE'

二、迭代

for循环遍历list、tuple、dict、字符串等,这种遍历成为迭代。

遍历dict:

>>> d={'a':1,'b':2,'c':3}#默认迭代的是key >>> for key in d: ...     print key ... a c b

>>> for value in d.itervalues():#迭代value ...     print value ... 1 3 2 >>> for k,v in d.iteritems(): #key、value一起迭代 ...     print k,v ... a 1 c 3 b 2

通过collections模块的Iterable类型可判断对象是否可迭代:

>>> from collections import Iterable >>> isinstance('abc',Iterable) True

import和from……import的区别:直接输Iterable到程序中,而不用使用collections.Iterable

>>> import collections >>> isinstance('abc',collections.Iterable) True

Python内置的enumerate函数可把list转变成索引-元素对,使得可以在for循环中迭代索引、元素对:

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

当然也可以:

>>> for i in range(3): ...     print i, ['A','B','C'][i] ...

for循环中同时引用两个变量还如:

>>> for x, y in [(1, 1), (2, 4), (3, 9)]: 

...     print x, y

 ... 

三、列表生成式

List Comprehensions,强大的创建list的生成式:

>>> range(1,11) #生成简单1~10 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] >>> L=[] >>> for i in range(1,11): #生成1*1 ~10*10 ...     L.append(i*i) ... >>> L [1, 4, 9, 16, 25, 36, 49, 64, 81, 100] >>> [i*i for i in range(1,11)] #简化上述循环 [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

>>> [i*i for i in range(1,11) if i%2 ==0]#后面还可跟if [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('.')] #listdir可列出文件和目录 ['a.py', 'a.pyc', 'b.py', 'def.py', 'math.py', 'test1.py', 'while.py']

上述二中,dict的key、value一起迭代的for循环也可以用列表生成式:

>>> d={'a':'A','b':'B','c':'C'}#key和value不是同种类型时好像有问题来着?报错了 >>> [k + '='+ v for k,v in d.iteritems()] ['a=A', 'c=C', 'b=B']

将list中的所有字符串变成小写:

>>> L=['Hello', 'World', 'Hello', 'Everyone'] >>> [s.lower() for s in L] ['hello', 'world', 'hello', 'everyone']

四、生成器

在Python中,这种一边循环一边计算的机制,称为生成器(Generator),这样可以节省内存,元素需要时再生成。

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 0x000000000312BA20> >>> g.next() 0 >>> g.next() 1 >>> for n in g: ...     print n ... 4 9 16 25 36 49 64 81

generator生成的第二种方法:

斐波拉契数列用列表生成式表达不出来,可用函数表达,在函数定义中包含yield关键字,就变成了generator:

def fib(max): n, a, b = 0, 0, 1 while n < max: yield b #将普通函数的print b a, b = b, a + b n=n + 1

五、

变量可以指向函数

>>> f=abs >>> f(-10) 10

函数名可以看成变量,如abs可以看成一个变量,指向一个可以计算绝对值的函数。

函数可以接收另一个函数作为参数,即高阶函数。

六、map()/reduce()

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

eg:

>>> def f(x): ...     return x*x ... >>> map(f,[1,2,3,4,5,6,7,8,9]) [1, 4, 9, 16, 25, 36, 49, 64, 81] >>> map(f,range(1,10)) [1, 4, 9, 16, 25, 36, 49, 64, 81]

>>> map(str,range(1,10)) ['1', '2', '3', '4', '5', '6', '7', '8', '9']

reduce用法。

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

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

eg:

序列求和

>>> def add(x, y): ...     return x + y ... >>> reduce(add, [1, 2, 3, 4]) 10

将字符串'13579'转成数字13579可使用reduce和map函数:

>>> def str2int(s): ...     def fx(x, y): ...             return x*10+y ...     def char2num(s): ...             return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s] ...     return reduce(fn, map(char2num, s)) ... >>> str2int('12345') 12345

可用lambda函数精简该函数:

>>> def char2num(s): ...     return {'0':0,'1':1,'2':2,'3':3,'4':4,'5':5,'6':6,'7':7,'8':8,'9':9}[s] ... >>> def str2int(s): ...     return reduce(lambda x, y: x*10+y, map(char2num, s)) ...

lambda函数:起到一个函数速写的作用。允许在代码内嵌入一个函数的定义

>>> f=lambda x, y, z: x+y+z >>> f(1,2,3) 6

练习:

1、利用 map() 函数,把用户输入的不规范的英文名字,变为首字母大写,其他小写的规范名字。输 入: ['adam', 'LISA', 'barT'] ,输出: ['Adam', 'Lisa', 'Bart'] 。

>>> def f(s): ...     L=[] ...     L.append(s[0:1].upper()) ...     for i in range(1,4): ...             L.append(s[i:i+1].lower()) ...     return ''.join(L) #''.join(L)可把list的各元素连起来转化成字符串,''单引号中可填用#什么连接各元素,如空格,加号 ...

>>> map(f, ['adam','LISA','barT']) ['Adam', 'Lisa', 'Bart']

2、Python提供的 sum() 函数可以接受一个list并求和,请编写一个 prod() 函数,可以接受一个list并利用 reduce() 求 积。

>>> L=[1,2,3,4]

>>> def mul(x,y): ...     return x*y ...

>>> def prod(L): ...     return reduce(mul,L) ... >>> >>> prod(L) 24

七、filter

Python内建的 filter() 函数用于过滤序列。

filter()接收一个函数和一个序列,把传入的函数一次作用于每个序列里的元素,来觉得是否舍弃该元素。

把一个序列的空字符串删掉:

>>> def not_empty(s): ...     return s and s.strip()# strip() 方法用于移除字符串头尾指定的字符(默认为空格)。 ... >>> filter(not_empty,['A', '', 'B', None, 'C', ' ']) ['A', 'B', 'C']

 strip() 方法用于移除字符串头尾指定的字符(默认为空格)。

>>> str="000000hello how are you00000" >>> str.strip('0') 'hello how are you' >>> str="    hello how are you    " >>> str.strip() 'hello how are you'

八、sorted

sorted函数可以对list排序

>>> sorted([4,2,5,11]) [2, 4, 5, 11]

sorted也可以接收一个比较函数实现自定义排序:

>>> def reversed_cmp(x,y): ...     if x>y: ...             return -1 ...     if x<y: ...             return 1 ...     return 0 ... >>> sorted([4,2,5,11], reversed_cmp) [11, 5, 4, 2]

九、函数作为返回值

高阶函数除了可以把函数作为入参,也可以把函数作为返回值

可变参数的求和,不是立即需要和,而是在后面的代码中,根据需要再计算怎么办?可以不返回求和的结果,而是返回求 和的函数!

>>> def lazy_sum(*args): ...     def sum(): ...             ar=0 ...             for n in args: ...                     ar=ar+n ...             return ar ...     return sum ...

>>> f <function sum at 0x000000000381EF28> >>> f() #调用f时,才真正计算求和结果

25

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

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

当 lazy_sum 返回函数 sum 时,相关参数和变量都保存在返回的函数中,这种称为“闭包(Closur e)”

返回闭包时牢记的一点就是:返回函数不要引用任何循环变量,或者后续会发生变化的变量。

十、装饰器

>>> def now(): ...     print '2013-12-25' ... >>> f=now >>> f() 2013-12-25

>>> f.__name__ #函数对象有个__name__属性,可以拿到函数的名字 'now'

们要增强 now() 函数的功能,比如,在函数调用前后自动打印日志,但又不希望修改 now() 函数的定 义,这种在代码运行期间动态增加功能的方式,称之为“装饰器”(Decorator)。

>>> def log(func): #定义一个能打印日志的decorator ...     def wrapper(*args, **kw): ...             print 'call %s():' % func.__name__ ...             return func(*args, **kw) ...     return wrapper ...

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

>>> @log #把@log放到此处,相当于执行了now=log(now) ... def now(): ...     print '2013-12-25' ...

>>> now() call now(): 2013-12-25

>>> now.__name__ 'wrapper'

上面@log处,相当于执行now=log(now),原来的now()函数仍存在,只不过现在同名的now变量指向了新的函数,

于是调用now()执行新的函数。

若decorator需传入参数

>>> 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') #相当于执行了log('execute')(now) ... def now(): ...     print '2013-12-25' ... >>> now() execute now(): 2013-12-25

此时:

>>> now.__name__ 'wrapper'

__name__从now变成了wrapper,需要把原始函数的 __name__ 等属性复制 到 wrapper() 函数中,import functools 后,在定义 wrapper() 的前面加 上 @functools.wraps(func) 即可。

练习:

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

十一、偏函数

Python的 functools 模块提供了很多有用的功能,其中一个就是偏函数(Partial function)

>>> int('100000',base=2) 32

若想把大量的二进制转化为十进制,可定义带默认参数base=2的函数int2来简化:

def int2(x, base=2):

return int(x, base)

functools.partial可不需要再自定义int2

>>> import functools >>> int2=functools.partial(int,base=2) >>> int2('100000') 32

可知functools.partial的作用是把函数的某些参数设为默认参数,返回一个新的函数。

创建偏函数,参数可以当做是①函数对象②*args③**kw这三个参数

故上面base=2可当做是固定了关键字参数。

>>> max2=functools.partial(max,10)#10作为*args的一部分传到左边 >>> max2(5,6,7) #max(10,5,6,7) 10

十二、模块

(一)

一个.py文件是一个模块。为避免不同人写的模块名字相同,可按目录来组织模块,称为包package。

每个包目录下有个__init__.py文件,可为空文件,也可有代码,它也是模块,模块名是包名。

#!/usr/bin/env python#使可以在Linux运行

# -*- coding: utf-8 -*-#使用标准utf-8编码

'test_module.py' #模块的第一个字符串被视为文档的注释,可用变量__doc__访问 __author__ = 'hello' #__author__作者 import sys def test(): args = sys.argv#sys模块的argv变量是个list,储存了所有变量,  

#执行python test_module.py hello aa时,sys.argv=['test_module.py',#'hello', 'aa'] if len(args)==1: print 'Hello World' print args elif len(args)==2: print 'Hello, %s' % args[1] print args else: print 'Too many arguments' print args if __name__=='__main__': #在命令行运行test_module模块时,Python解释器把变量__name__置为#__main,若在其他地方import test_module时,不执行test()函数 test()

print ' aaaaa ',__name__#导入时,__此处__name__为test_module

(二)模块别名

try: 

import cStringIO as StringIO#优先使用cStringIO

except ImportError: # 导入失败会捕获到ImportError

import StringIO#导入cStringIO失败才用StringIO

(三)模块函数变量作用域

公有变量:可被外部访问,如abc

私有变量:不希望被外部访问,定义时可用_前缀,如_abc

特殊变量:__name__、__doc__、__author__等

(四)搜索路径

>>> import sys

>>> sys.path ['', 'C:\\WINDOWS\\SYSTEM32\\python27.zip', 'C:\\Python27\\DL Ls', 'C:\\Python27\\lib', 'C:\\Python27\\lib\\plat-win', 'C:\ \Python27\\lib\\lib-tk', 'C:\\Python27', 'C:\\Python27\\lib\\ site-packages']

>>>sys.path.append('********')

十三、__future__模块

该模块提供把Python下个版本的特性代码导入当前版本,来测试新版本特性。

在2.7的版本中,可使用unicode_literals来使用3.x的版本的字符串表示方法:2.7的'xxx'表str,u'xxx'表unicode,3.x的'xxx'和u'xxx'都表unicode,3.x以'xxx'表示的str前面必须加b,即b'xxx',表二进制字符串。

from __future__ import unicode_literals

在2.x中运行3.x的除法,可用__future__中的division实现:2.x中,两整数相除也为整数,3.x两整数相除都为精确商,若得到像2.x的整数结果,可用//表示。

转载请注明原文地址: https://www.6miu.com/read-17533.html

最新回复(0)