python学习笔记(三)
一、高级特性
1、切片
取list或tuple中的一部分元素,可使用切片操作符(:)。
l = ['michael', 'sarah', 'tracy', 'bob', 'jack'] #取前三个元素 >>>l[0:3] ['michael', 'sarah', 'tracy'] #索引号第1个是0,可省略 >>>l[:3] ['michael', 'sarah', 'tracy'] #取第1-3个字元素 >>>l[1:4] ['sarah', 'tracy', 'bob']
也可以倒数取:
l = list(range(100)) >>> l [0, 1, 2, 3, ..., 99] #取最后10个数 >>>l[-10:] [90, 91, 92, 93, 94, 95, 96, 97, 98, 99] #取倒数第二个数 >>>l[-2,-1] [98]
也可以每n个取出元素:
>>> l[:10:2] #前10个数,每两个取一个 [0, 2, 4, 6, 8] >>> l[::5] #所有数,每5个取一个 [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95]
2、迭代
可用for循环遍历集合对象中所有元素的行为,称为迭代(iteration)。
可迭代的对象:list、tuple、dict、set、字符串等。
d = {'a': 1, 'b': 2, 'c': 3} for key in d: #dict默认只迭代key值 print (key) for value in d.values() #迭代value值 print (value) for k,v in d.items() #迭代key和value值 print (k, v)
需要将list实现迭代时出现索引下标,可用enumerate函数:
for i, value in enumerate(['a', 'b', 'c']): print(i, value)
判断一个对象是否可迭代,可用collections模块的iterable类型判断:
>>>from collections import iterable >>>isinstance('abc', iterable) #判断字符串是否可迭代 true >>>isinstance(123, iterable) #判断整数是否可迭代 false
3、列表生成式
list(range(1,11))可以生成[1,2,3,....10]的list。
但如果要生成[1*1, 2*2, 3*3, ..., 10 * 10]这样的列表,除了用循环算法,还可以用列表生成式:[x * x for x in range(1,10)]
列表生成式的格式:[表达式 for x in range()]
for循环后加上if判断,可筛选for循环的结果:
>>> [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']
使用两个变量来生成list:
>>> d = {'x': 'a', 'y': 'b', 'z': 'c' } >>> [k + '=' + v for k, v in d.items()] ['y=b', 'x=a', 'z=c']
if...else可以用在表达式当中:
[x if x % 2 == 0 else -x for x in range(1, 11)] [-1, 2, -3, 4, -5, 6, -7, 8, -9, 10]
>>> l = [x * x for x in range(10)] >>> l [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
则list会直接生成出来。但是如果生成十万百万个这样的元素,则会消耗掉内存,可使用生成器来代替上面的列表生成式:
>>> g = (x * x for x in range(10))
def g(): for x in range(10): yield x*x return 'end'
函数体内包含yield则此函数为generator。
要调用该generator时,首先要生成一个generator对象,然后再用next()函数不断获得下一个yield的返回值。
o = g() while true: try: x = next(o) print('g:', x) except stopiteration as e: #使用stopiteration捕获return值 print('generator return value:', e.value) break
也可以用for循环来不断获得返回值,这时不需要next()函数,也不会产生stopintertaion错误。
for n in g(): print(n)
5、迭代器
可以for循环的数据类型有两种:
一种是集合类型,归属于interable对象,比如:list、tuple、dict、set、str等;
一种是generator生成器,这类归属于iterator对象。
把list
、dict
、str
等iterable
变成iterator
可以使用iter()
函数:
>>> isinstance(iter([]), iterator) true >>> isinstance(iter('abc'), iterator) true
二、函数式编程
函数式编程的重要特点:函数本身可以作为参数传入到另一个函数,还允许返回一个函数。
python对函数式编程提供部分支持。
(一)函数作为参数传入:
1、map和reduce函数
map():接收两个参数,一个是函数(此函数只有一个参数),一个是iterable,作用是将传入的函数作用到传入序列的每一个元素上。
def f(x): return x * x; r=map(f, [1,2,3,4,5,6,7,8,9]) list(r) #结果:[1,4,9,16,25,36,49,64,81]
reduce():把一个函数作用在一个序列上,该函数必须有两个参数,接收序列中前两个的累积结果和下一个元素。效果如下:
reduce(f, [x1,x2,x3,x4]) = f(f(f(x1,x2), x3), x4)
from functools import reduce def add(x, y): return x + y reduce(add, [1, 3, 5, 7, 9]) #序列累积求和:25
2、filter函数
通过传入的函数,对序列进行过滤。传入的函数返回值必须是布尔值。
#去掉偶数,只保留奇数 def is_odd(n): return n % 2 == 1 list(filter(is_odd, [1, 2, 4, 5, 6, 9, 10, 15])) # 结果: [1, 5, 9, 15]
3、sorted排序函数
sorted()函数有三个参数,第一参数是要接受排序的序列,第二参数可选,用于在排序前对序列作用于每个元素,第三参数可选,默认为false,设为true则表示反向排序。
sorted(['bob', 'about', 'zoo', 'credit']) #按ascii码排序: ['credit', 'zoo', 'about', 'bob'] sorted(['bob', 'about', 'zoo', 'credit'], key=str.lower) #对每个元素变小写,再按ascii码排序:['about', 'bob', 'credit', 'zoo'] sorted(['bob', 'about', 'zoo', 'credit'], key=str.lower, reverse=true) #每个元素变小写,再按ascii码反向排序:['zoo', 'credit', 'bob', 'about']
(二)函数作为返回值:
函数可作为返回值返回,此时返回的函数体并不会立即执行。
#返回求和函数 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时,才会计算求和结果 f() #结果:25
注意:返回的函数体不要引用局部会变化的变量,否则会引起预想不到的结果。
(三)匿名函数
py的匿名函数写法:
lambda <参数>:返回函数体结果。
匿名函数的限制:只有有一个表达式,不用写return,返回值就是该表达式的结果。
f = lambda x:x*x #实际上就是: def f(x): return x*x
(四)装饰器decorator
当需要增强函数功能时,可使用装饰器decorator。
比如,在调用now()函数前显示自动打印函数日志。
def log(func): def wrapper(*args, **kw): print('调用 %s():' % func.__name__) return func(*args, **kw) return wrapper #要使用上面的封装器,则可这样使用: @log def now(): print('2020-04-14') #调用now() now() #显示: #call now(): #2020-04-14
(五)偏函数partial function
偏函数的作用:把一个函数的某些函数用某个值固定,并返回一个新函数,可以简单调用。
举例:
int()函数可把字符串转换为整数,传入字符串时,会默认按十进制转换。此函数的第二个参数为默认值 10,可以用偏函数固定成其他值:
import functools int2 = functools.partial(int, base=2) int2('1000000') #结果:64
三、模块
模块作用:将代码利用模块分隔开,利于维护;
python:一个.py文件为一个模板,一个文件夹为一个package(文件夹下必须包含__init__.py)。
模块名起名规范:遵循py变量命名规范,不要使用中文和特殊字符,不要与系统模块名冲突;
示例:
mycompany ├─ web │ ├─ __init__.py │ ├─ utils.py │ └─ www.py ├─ __init__.py ├─ abc.py └─ utils.py
文件www.py的模板名为:mycompany.web.www。utils.py模块名分别有:mycompany.web.utils和mycompany.utils。
引用模块:
import 模块名
python在指定的路径下搜索对应的.py文件来加载模块。包括:当前目录、所有已安装的内置模块和第三模块目录。这些目录存放在sys模块下的path变量中。
>>> import sys >>> sys.path ['', '/library/frameworks/python.framework/versions/3.6/lib/python36.zip', '/library/frameworks/python.framework/versions/3.6/lib/python3.6', ..., '/library/frameworks/python.framework/versions/3.6/lib/python3.6/site-packages']
添加模块搜索目录的方法:
(1)运行时添加:
>>> import sys >>> sys.path.append('/users/michael/my_py_scripts')
这种方法在运行时添加,运行完后失效。
(2)设置pythonpath环境变量
这种方式与path环境变量类似。
模块文件的编写规范:
#!/usr/bin/env python3 # -*- coding: utf-8 -*- ' a test module ' __author__ = 'michael liao' import sys def test(): args = sys.argv if len(args)==1: print('hello, world!') elif len(args)==2: print('hello, %s!' % args[1]) else: print('too many arguments!') if __name__=='__main__': test()
前两行为标准注释;
第4行是一个模块的文档注释,任何模块代码第一个字符串都被视为模块的文档注释;
第6行__author__变量是作者名。
而后的代码就是真正的代码部分。
最后两行,__name__变量是特殊变量,当模块在命令行模式运行时此变量为__main__字符串,常用于运行测试。
另外说明一点:
模块中的函数和变量都是公开的,无公有或私有化一说。只是我们自己可以规定_或__开头的应该业内口头规定为私有变量或函数,但实际上仍可以被外部调用。
安装第三方模块:
在安装了python后,可以使用pip(3版本为pip3)命令安装第三方库。
第三方库一般都在 中注册。
安装常用模块,可以使用anaconda更方便。下载地址:https://www.anaconda.com/download/
有关介绍说明:
上一篇: 立秋时吃什么蔬菜?立秋后天气还热吗?
下一篇: 处暑节吃啥水果?处暑小知识