Python计算


第1章 基础知识

1.4.1 对象模型

• 对象:python中处理的每样“东西”都是对象

• 内置对象:可直接使用

如 数字、字符串、列表、del等;

• 非内置对象:需要导入模块才能使用

如 sin(x),random( )等。

对象类型 示例
数字 1234,3.14
字符串 ‘Python’
日期 2012-08-25
字典 [1,2,3]
元组 {1:’food’,2:’taste’}
文件 (1,2,3)
集合 f=open(‘data.dat’,’r’)
布尔型 True,False
空类型 None
编程单元类型 函数、模块、类

1.4.2 Python变量

• 不需要事先声明变量名及其类型

• 直接赋值即可创建各种类型的对象变量

内置函数type()用来返回变量类型

isinstance()用来测试对象是否为指定类型的实例

id()用来返回变量所指值的内存地址

x=3
print(type(x))
isinstance(x,int)
id(x)

• Python采用基于值的内存管理方式

• Python如果为不同变量赋值为相同值,这个值在内存中只有一份,多个变量指向同一块内存地址

1.4.3 数字

• 数字:python中最常用的不可变对象

• 可以表示任意大小的数字

1.4.4 字符串

• 用单引号、双引号或三引号括起来的符号系列称为字符串

• 单引号、双引号、三单引号、三双引号可以互相嵌套,用来表示复杂字符串。

‘abc’、’123’、’中国’、”Python”

• 字符串属于不可变序列

• 空串表示为’’或 “”

• 三引号’’’或”””表示的字符串可以换行

• 三引号’’’或”””可以在程序中表示较长的注释

1.4.5 操作符和表达式

运算符示例 功能说明
x//y 求整商
x**y 幂运算
x in y;x not in y 成员测试运算符
x is y;x is not y 对象实体同一性测试(地址)
&、|、^ 集合交集、并集、对称差集

在Python中逗号”,”并不是运算符,而只是一个普通分隔符。

'a' in 'b','a'
# (False,'a')
x=3,5
# (3,5)

1.4.6 常用内置函数

函数 功能
chr(x) 返回ASCII编码或Unicode编码为x的字符
dir(x) 返回指定对象或模块的成员列表
help(obj) 返回对象obj或模块的帮助信息
eval() 计算字符串中表达式的值并返回
isinstance(obj,type) 测试对象是否属于指定类型的实例
len(obj) 返回对象obj包含的元素个数
map(函数,序列) 将单参数函数映射至序列中每个元素,返回map对象
ord(s) 返回一个字符s的ASCII码
pow(x,y) 返回x的y次方,等价于x**y
range([start,]end[,step]) 返回一个等差数列列表(py3.x返回一个range对象),不包括终值
reduce(函数,序列) 将接受2个参数的函数以累积的方式从左到右依次应用至序列中每个元素,最终返回单个值作为结果
reversed(列表或元组) 返回逆序后的迭代器对象
round(x[,小数位数]) 对x进行四舍五入,若不指定小数位数,则返回整数
sorted(列表[,reverse]) 返回排序后的列表
zip(seq1[,seq2[…]]) 返回zip对象

1.4.7 对象的删除

  • Python自动内存管理功能:
    • 解释器跟踪所有值,没有变量指向的自动删除
    • 自动内存管理不保证及时释放内存
    • 显示释放申请的资源是程序员的好习惯和素养
  • del命令
    • 显示删除对象
    • 解除与值之间的指向关系

1.4.8 基本输入输出

在Python中,使用内置函数input()来接受用户的键盘输入,input()函数的一般用法为

x=input('提示:')
print(i,end=' ')

输出内容之后不换行

1.4.9 模块导入与使用

  1. import 模块名[as 别名]
  2. from 模块名 import 对象名[as 别名]

第2章 Python序列

  • 序列: 一系列相关的按一定顺序排列的值

  • 序列是程序设计中经常用到的数据存储方式

  • Python提供的序列类型最丰富,最灵活,功能最强大

  • Python序列结构:列表、元组、字典、字符串、集合、range

  • 列表、元组、字符串等序列均支持双向索引

    第一个元素下标为0,第二个元素下标为1,以此类推;

    最后一个元素下标为-1,倒数第二个元素下标为-2,以此类推

2.1 列表

  • 内置可变序列
  • 若干元素的有序集合
  • 列表中的每一个数据称为元素
  • 列表的所有元素放在一对中括号“[”和“]”中,并使用逗号分隔开

列表元素增加或删除:

  • 对象自动进行扩展或收缩内存,保证元素之间没有缝隙

列表中的数据类型可以各不相同:

  • 可以同时分别为整数、实数、字符串等基本类型

  • 可以是列表、元素、字典、集合以及其他自定义类型的对象

    [10, 20, 30, 40] [‘spam’, 2.0, 5, [10, 20]]

    [‘crunchy frog’, ‘ram bladder’, ‘lark vomit’]

    [[‘file1’, 200,7], [‘file2’, 260,9]]

方法 说明
list.append(x) 将元素x添加至列表尾部
list.extend(L) 将列表L中所有元素添加至列表尾部
list.insert(index, x) 在列表指定位置index处添加元素x
list.remove(x) 在列表中删除首次出现的指定元素
list.pop([index]) 删除并返回列表对象指定位置的元素
list.index(x) 返回值为x的首个元素的下标
list.count(x) 返回指定元素x在列表中的出现次数
list.reverse() 对列表元素进行原地逆序
list.sort() 对列表元素进行原地排序

删除列表中指定元素的所有重复

由于Python会自动对列表进行收缩并移动列表元素

应该使用切片来避免:

x=[1,2,1,2,1,1,1]
for i in x[::]:
    if i==1:
        x.remove(i)

也可以使用从后向前的顺序来删除列表中的重复元素

x=[1,2,1,2,1,1,1]
for i in range(len(x)-1-1-1):
    if x[i]==1:
        del x[i]

2.1.6 切片操作

切片使用2个冒号分隔的3个数字来完成:第一个数字表示切片开始位置(默认为0),第二个数字表示切片截止(但不包含)位置(默认为列表长度),第三个数字表示切片的步长(默认为1)。

切片操作不会因为下标越界而抛出异常

  • 可以使用切片来截取列表中的任何部分
  • 可以通过切片来修改和删除列表中部分元素
  • 可以通过切片操作为增加元素

不影响列表对象内存地址

切片返回的是列表元素的浅复制,与列表对象的直接赋值并不一样

aList=[3,5,6,9]
print(id(aList))
bList=aList[::]
print(id(bList))

2.1.7 列表排序

import random
random.shuffle(aList) #打乱顺序
aList.sort() #默认为升序排列
aList.sort(reverse=True) #降序排列
aList.sort(key=lambda x: len(str(x)))#自定义排序

内置函数sorted()返回新列表,并不对原列表进行任何修改

内置函数reversed()不对原列表做任何修改,而是返回一个逆序排列后的迭代对象

aList=[3,4,5,6,7]
newList=reversed(aList)
list(newList) #使用第一次
for i in newList:
    print(i,end=' ')  #没有输出

在之前的list()函数执行时,迭代器对象已遍历结束,需要重新创建迭代对象才能再次访问其内容。

max、sum(列表)默认对字典“键”进行计算,如果需要对字典”值”进行计算,则需要使用字典的**values()**方法明确说明

**zip(列表1,列表2,…)**:将多个列表或元组对应位置的元素组合为元组,并返回包含这些元组的zip对象

aList=[1,2,3]
bList=[4,5,6]
cList=zip(aList,bList)#zip对象
list(cList)

enumerate(列表)

枚举列表、元组或其他可迭代对象的元素,返回枚举对象,枚举对象中每个元素是否含下标元素值元组

for item in enumerate(cList):
    print(item)
'''
(0,(1,4))
(1,(2,5))
(2,(3,6))
''' 

2.1.9 列表推导式

aList=[v.strip() for v in freshfruit]等价于下面的代码:

freshfruit=[' banana ',' apple  ']
freshfruit=list(map(str.strip,freshfruit))
for i,v in enumerate(freshfruit):
    freshfruit[i]=v.strip()
print(freshfruit)
  1. 使用列表推导式实现嵌套列表的平铺

    vec=[[1,2,3],[4,5,6],[7,8,9]]
    [num for elem in vec for num in elem]
    
  2. 过滤不符合条件的元素

    • 列出当前文件夹下所有Python源文件
    import os
    [filename for filename in os.listdir('.') if filename.endswith('.py')]
    
  3. 在列表推导式中使用多个循环,实现多序列元素的任意组合,并且可以结合条件语句过滤特点元素

    [(x,y) for x in range(3) for y in range(3)]
    
  4. 使用列表推导式实现矩阵转置

    matrix=[[1,2,3,4],[5,6,7,8],[9,10,11,12]]
    [[row[i] for row in matrix] for i in range(4)]
    

    也可以使用内置函数zip()和list()来实现矩阵转置:

    list(zip(*matrix))
    
  5. 列表推导式中可以使用函数或复杂表达式

    def f(v):
        if v%2==0:
            v=v**2
        else:
            v=v+1
        return v
    print([f(v) for v in [2,3,4,-1] if v>0])
    print([v**2 if v%2==0 else v+1 for v in [2,3,4,-1] if v>0])
    
  6. 列表推导式支持文件对象迭代

  7. 使用列表推导式生成100以内的所有素数

    [p for p in range(2,100) if 0 not in [p%d for d in range(2,int(sqrt(p))+1)]]
    

2.1.10 使用列表实现向量运算

在Python中,列表支持与整数的乘法运算,表示列表元素进行重复并生成新列表,不对原列表进行任何修改。不支持与整数的加减除运算,也不支持列表之间的减乘除操作。

2.2 元组

2.2.1 元组的创建与删除

如果要创建只包含一个元素的元组,只把元素放在圆括号里是不行的,还需要在元素后面加一个逗号“,”,而创建包含多个元素的元组则没有这个限制。

a_tuple=('a',)
a_tuple=('a','b','c')
s=tuple()#空元组

对于元组而言,只能使用del命令删除整个元组对象,而不能只删除元组中的部分元素,因为元组属于不可变序列。

元组的访问和处理速度比列表更快。可用作字典的键。

2.2.2 元组与列表的区别

  • 元组中的数据一旦定义就不允许更改。
  • 元组没有append()、extend()和insert()等方法,无法向元组中添加元素;
  • 元组没有remove()或pop()方法,也无法对元组元素进行del操作,不能从元组中删除元素。
  • 内建的tuple( )函数接受一个列表参数,并返回一个包含同样元素的元组,而list( )函数接受一个元组参数并返回一个列表。从效果上看,tuple( )冻结列表,而list( )融化元组。

2.2.3 序列解包

  • 可以使用序列解包功能对多个变量同时赋值

    x,y,z=1,2,3
    print(x,y,z)
    
  • 序列解包对于列表和字典同样有效

a=[1,2,3]
b,c,d=a

s={'a':1,'b':2,'c':3}
b,c,d=s.items()
  • 使用序列解包可以很方便地同时遍历多个序列

    keys=['a','b','c','d']
    values=[1,2,3,4]
    for k,v in zip(key,values):
        print(k,v)
    
  • 在调用函数时,在实参前面加上一个星号(*)也可以进行序列解包,从而实现将序列中的元素值依次传递给相同数量的形参,

  • 利用 * 表达式获取单个变量中的多个元素

  • * 获取的值默认为 list

a, b, *c = 0, 1, 2, 3
#c=[2,3]
x={*{'a':1,'b':2}}
y={**{'a':1,'b':2}}
print(type(x))#<class 'set'>,&#123;'b','a'&#125;
print(type(y))#<class 'dict'>
def demo(a,b,c,d):
    print(a,b,c,d)
demo(**&#123;'a':1,'c':3&#125;,**&#123;'b':2,'d':4&#125;) #调用函数时参数序列解包

print(&#123;'x':1,**&#123;'y':2&#125;&#125;) #字典要用两个**

2.2.4 生成器推导式

  • 生成器推导式使用圆括号,列表推导式使用方括号
  • 生成器推导式的结果是一个生成器对象,不是列表或元组
  • 生成器对象的元素可根据需要转化为列表或元组
  • 可以使用生成器对象的next()方法进行遍历
  • 可以直接将其作为迭代器对象来使用。
  • 不管用哪种方法访问其元素,当所有元素访问结束以后,如

果需要重新访问其中的元素,必须重新创建该生成器对象。

g=((i+2)**2 for i in range(4))
print(tuple(g))
#(4,9,16,25)
tuple(g) #元素已经遍历结束 ()

2.3 字典

  • 字典是键值对的无序可变集合
  • 字典元素的键和值用冒号分隔,元素之间用逗号分隔,所有的元素放在一对大括号“{”和“}”中
  • 字典中的每个元素包含两部分:键和值,向字典添加一个键的同时,必须为该键增添一个值。
  • 字典中的键可以为任意不可变数据
  • 字典中的键不允许重复
  • globals()返回包含当前作用域内所有全局变量和值的字典
  • locals()返回包含当前作用域内所有局部变量和值的字典

2.3.1 字典创建与删除

  • 使用=将一个字典赋值给一个变量
  • 使用dict利用已有数据创建字典:
  • 使用dict根据给定的键、值创建字典
  • 以给定内容为键,创建值为空的字典
  • 使用del删除整个字典

给定内容为“键”,创建“值”为空的字典:

adict=dict.fromkeys(['name','age'])
print(adict)

2.3.2 字典元素的读取

  • 以键作为下标可以读取字典元素,若键不存在则抛出异常
  • 使用字典对象的get方法获取指定键对应的值,并且可以在键不存在的时候返回指定值。
aDict=&#123;'name':'Dong','sex':'male'&#125;
print(aDict.get('address'))
# None
print(aDict.get('address','abb'))
#abb
  • 使用字典对象的items方法可以返回字典的键、值对列表
  • 使用字典对象的keys方法可以返回字典的键列表
  • 使用字典对象的values方法可以返回字典的值列表

2.3.3 字典元素的添加与修改

  • 当以指定键为下标为字典赋值时,若键存在,则可以修改

该键的值;若不存在,则表示添加一个键、值对

  • 使用字典对象的update方法将另一个字典的键、值对添加到当前字典对象
  • 使用del删除字典中指定键的元素
  • 使用字典对象的clear方法来删除字典中所有元素
  • 使用字典对象的pop 方法删除并返回指定键的元素
  • 使用字典对象的popitem方法删除并返回字典中的元素

使用collections模块的Counter类可以统计元素次数

from collections import Counter
frequences=Counter(z)
frequences.most_common(1)
#返回次数最多的
frequences.most_common(3)
#返回次数前三多的

字典推导式

&#123;i:str(i) for i in range(1,5)&#125;
#&#123;1:'1',2:'2',3:'3',4:'4'&#125;

有序字典

x=collections.OrderedDict()#有序字典

2.4 集合

– 无序可变集合

– 使用一对大括号界定

– 元素不可重复

2.4.1 集合的创建与删除

  • 直接将集合赋值给变量

  • 使用del删除整个集合

  • 使用add()方法增加元素

  • 使用集合对象的pop()方法

  • 使用集合对象的remove()方法

  • 使用集合对象的clear()方法清空集合

2.4.2 集合操作

  • 交集、并集、差集等运算 (|,&,-,^)
  • 使用集合快速提取序列中单一元素

集合推导式

2.5 sorted()

内置函数sorted()返回新的列表,并不对原列表做任何修改

可以对元组、字典排序,且借助于key参数可以实现更加复杂的排序

persons=[&#123;'name':'Dong','age':37&#125;,&#123;'name':'Zhang','age':40&#125;,&#123;'name':'Li','age':50&#125;,&#123;'name':'Dong','age':43&#125;]
print(sorted(persons,key=lambda x:(x['name'],-x['age'])))
# [&#123;'name': 'Dong', 'age': 43&#125;, &#123;'name': 'Dong', 'age': 37&#125;, &#123;'name': 'Li', 'age': 50&#125;, &#123;'name': 'Zhang', 'age': 40&#125;]

使用key来指定排序依据,先按姓名升序排序,姓名相同的按年龄降序排序

第3章 选择与循环

3.1 条件表达式

• 算术运算符:+、-、、/、//、%、*

• 关系运算符:>、<、==、<=、>=、!=

• 测试运算符:in、not in、is、is not

• 逻辑运算符:and、or、not,注意短路求值

• 位运算符:~、&、|、 ^、 <<、>>

• 几乎所有的Python合法表达式都可以作为条件表达式,包括含有函数调用的表达式。

• 条件表达式的值只要不是False、0(或0.0、0j等)、空值None、空列表、空元组、空集合、空字典、空字符串、空range对象或其他空迭代对象,Python解释器均认为与True等价。

• 特殊逻辑运算符“and”和“or”:短路求值或惰性求值

• 设计条件表达式表示复杂条件时巧用“and”和“or”(如果能够大概预测不同条件失败的概率)提高程序效率,减少不必要的计算与判断

• “and”例:“表达式1 and 表达式2”

if“表达式1”=“False”,不论“表达式2”的值是什么,整个表达式的值都是“False”

• Python条件表达式中不允许使用赋值运算符“=”

3.2 选择结构

• Python双分支表达式:

value1 if condition else value2

–condition的值与True等价时,表达式的值为value1

–否则表达式的值为value2

–value1和value2中可以使用复杂表达式如函数调用

–双分支结构的表达式具有惰性求值的特点

• Python多分支结构:

if 表达式1:

语句块1

elif 表达式2:

语句块2

elif 表达式3:

语句块3

else:

语句块4

关键字elif是else if的缩写

3.3 循环结构

• Python基本的循环语句——while语句、for语句

• while循环一般用于循环次数难以提前确定的情况

• for循环一般用于循环次数可以提前确定的情况

• 优先考虑使用for循环

• 循环结构之间可以互相嵌套

• 循环语句语法

while 表达式:

循环体

for 取值 in 序列或迭代对象:

循环体

• 循环的else子句

循环自然结束时执行else结构中的语句

while 表达式:

​ 循环体

else:

​ else子句

for 取值 in 序列或迭代对象:

​ 循环体

else:

​ else子句

  • 编写循环语句时,减少循环内部不必要的计算
  • 与循环变量无关的代码提取到循环之外
  • 使用多重循环嵌套减少内层循环中不必要的计算
  • 循环中尽量引用局部变量,查询和访问速度比全局变量略块

3.4 break和continue语句

• break语句在while循环和for循环中使用

一般放在if选择结构中,使得整个循环提前结束

• continue语句的作用是终止当前循环

并忽略continue之后的语句,提前进入下一次循环

• 除非break语句让代码更简单或更清晰,否则不要轻易使用

在循环中应尽量使用局部变量,因为局部变量的查询和访问速度比全局变量略快;在使用模块中的方法时,可以通过将其转换为局部变量来提高运行速度。

总结:

  1. 几乎所有合法的Python表达式都可以作为选择结构和循环结构中的条件表达式
  2. Python的关系运算符可以连续使用,例如3<4<5>2的值为True

第4章 字符串与正则表达式

Python中字符串

• 属于序列类型

• 支持序列通用方法和切片操作

• 支持特有的字符串操作方法

• 字符串属于不可变序列类型

Python字符串驻留机制

• 短字符串赋给多个对象时,内存中只有一个副本

• 长字符串不遵守驻留机制

• 判断一个变量s是否为字符串

• 使用isinstance ( s, basestring )

字符串格式化

%s:字符串(str)

%r:字符串(repr)

%c:单个字符

%d:十进制整数 %o:八进制整数

%x:十六进制整数 %f:浮点数

字符串常用方法

• find( )、rfind()

查找一个字符串在另一个字符串指定范围(默认是整个字符串)中首次和最后一次出现的位置,如果不存在则返回-1

s="apple,peach,banana,peach,pear"
s.find("peach") #返回第一次出现的位置
s.find("peach",7)#从指定位置开始查找
s.find("peach",7,20)#从指定范围中查找
s.rfind("p")#从字符串尾部向前查找

• index()、rindex()

返回一个字符串在另一个字符串指定范围中首次和最后一次出现的位置,如果不存在则抛出异常

s.index('p') #返回首次出现位置
s.index('pe')
s.rindex('p')#返回最后一次出现的位置

• count()

返回一个字符串在另一个字符串中出现的次数

s.count('p')    #统计子字符串出现次数

• split()、rsplit()

用来以指定字符为分隔符,将字符串左端和右端开始将其分割成多个字符串,并返回包含分割结果的列表

  • 如果不指定分隔符,则字符串中的任何空白符号(包括空格、换行符、制表符等)都被认为是分隔符
  • 还允许指定最大分割次数
s="apple,peach,banana,pear"
li=s.split(",")  #使用逗号分割
#["apple","peach","banana","pear"]
s='\n\nhello\t\t world \n\n My name\t is Dong '
s.split(None,2)
#['hello','world','My name is Dong ']
s.rsplit(None,2)
#['\n\nhello\t\t world \n\n\n My name','is','Dong']

• partition()、rpartition()

指定字符串为分隔符将原字符串分割为3部分,即分隔符前的字符串、分隔符字符串、分隔符后的字符串,如果指定的分隔符不在原字符串中,则返回原字符串和两个空字符串

s.partition(',')
('apple',',','peach,banana,pear')
s.rpartition(',')
('apple,peach,banana',',','pear')

• join()

与split()相反,join()方法用来将列表中多个字符串进行连接,并在相邻两个字符串之间插入指定字符

li=["apple","peach","banana","pear"]
sep=","
s=sep.join(li)
#"apple,peach,banana,pear"

lower()、upper()、capitalize()、title()、swapcase()

分别用来将字符串转换为小写、大写字符串、将字符串首字母变为大写、将每个单词的首字母变为大写以及大小写互换

• replace()

用来替换字符串中指定字符或子字符串的所有重复出现,每次只能替换一个字符或一个子字符串

• maketrans()、translate()

maketrans()方法用来生成字符映射表,而translate()方法则按映射表关系转换字符串并替换其中的字符,使用这两个方法的组合可以同时处理多个不同的字符。

table=''.maketrans('abcdef123','uvwxyz@#$')
s="Python is a greate programming language. I like it!"
s.translate(table)
#"Python is u gryuty progrumming lunguugy. I liky it!"

• strip()、rstrip()、lstrip()

用来删除两端、右端或左端的空白字符或连续的指定字符

s="  abc  "
s2=s.strip()  #删除空白字符
"aaaaassddf".strip("a") #删除指定字符
#"ssddf"
"aaaassddfaaa".rstrip('a')#删除字符串右端指定字符
#'aaaassddf'
"aaaassddfaaa".lstrip('a')#删除字符串左端指定字符
#'ssddfaaa'

• eval()

内置函数eval()尝试把任意字符串转化为Python表达式并求值

• 关键字in

与列表、元组、字典、集合一样,也可以使用关键字in和not in来判断一个字符串是否出现在另一个字符串中,返回True或False

• startswith()、endswith()

用来判断字符串是否以指定字符串开始或结束。这两个方法可以接收两个整数参数来限定字符串的检测范围。

s="Beautiful is better than ugly."
s.startswith('Be',0,5)
#True

• isalnum()、isalpha()、isdigit()、isspace()、isupper()、islower()

用来测试字符串是否为数字或字母、是否为字母、是否为数字字符、是否为空白字符、是否为大写字母以及是否为小写字母。

• center()、ljust()、rjust()

返回指定宽度的新字符串,原字符串居中、左对齐或右对齐出现在新字符串中,如果指定的宽度大于字符串长度,则使用指定的字符(默认为空格)填充。

'Hello world!'.center(20)
#'    Hello world!   '
'Hello world!'.center(20,'=')
#'====Hellow world!===='
'Hello world!'.ljust(20,'=')
#'Hello world!========'
'Hello world!'.rjust(20,'=')
#'========Hello world!'

• 字符串常量

import string

string.digits——‘0123456789’

string.punctuation——‘!”#$%&'()*+,-./:;<=>?@[\]^_`{|}~’

string.letters——‘ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz’

string.printable——‘0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRS

TUVWXYZ!”#$%&'()*+,-./:;<=>?@[\]^_`{|}~\t\n\r\x0b\x0c’

string.lowercase——‘abcdefghijklmnopqrstuvwxyz’

string.uppercase——‘ABCDEFGHIJKLMNOPQRSTUVWXYZ’

random标准库

choice()用于从序列中任意选择一个元素的函数

getrandbits()用于生成指定二进制位数的随机整数的函数

randrange()和randint()生成指定范围内随机数的函数

shuffle()列表原地乱序函数

sample()从序列中随机选择指定数量不重复元素的函数

4.2 正则表达式

• 正则表达式

字符串处理的有力工具和技术

• 正则表达式原理

使用预定义模式去匹配一类具有共同特征的字符串

处理字符串:快速、准确地完成复杂的查找、替换等

• Python中re模块提供了正则表达式操作所需要的功能。

.:匹配除换行符以外的任意单个字符

*:匹配位于 *之前的0个或多个字符

+:匹配位于+之前的一个或多个字符

|:匹配位于|之前或之后的字符

^:匹配行首,匹配以^后面的字符开头的字符串

$:匹配行尾,匹配以$之前的字符结束的字符串

?:匹配位于?之前的0个或1个字符

\:表示位于\之后的为转义字符

[]:匹配位于[]中的任意一个字符

-:用在[]之内用来表示范围

():将位于()内的内容作为一个整体来对待

{}:按{}中的次数进行匹配

\b:匹配单词头或单词尾

\B:与\b含义相反

\d:匹配任何数字,相当于[0-9]

\D:与\d含义相反

\s:匹配任何空白字符

\S:与\s含义相反

\w:匹配任何字母、数字以及下划线,相当于[a-zA-Z0-9_]

\W:与\w含义相反

re模块的主要方法

• compile(pattern[,flags]):创建模式对象

• search(pattern,string[,flags]):寻找模式

• match(pattern,string[,flags]):匹配模式

• findall(pattern,string[,flags]):列出模式的所有匹配项

• split(pattern,string[,maxsplit=0]):分割字符串

• sub(pat,repl,string[,count=0]):用repl替换pat的匹配项

• escape(string):将字符串中所有特殊正则表达式字符转义

flags值的说明:

re.I 忽略大小写 re.L/re.M 多行匹配模式
re.S 使元字符.匹配任意字符,包括换行符 re.U 匹配Unicode字符
re.X 忽略模式中的空格,并可以使用#注释 使用”|”进行组合

子模式与match对象

• 使()表示一个子模式, ()内的内容作为一个整体出现

• 正则表达式对象的match方法和search方法匹配成功后返回

match对象。

• match对象的主要方法

group()、groups()、groupdict()、start()、end()、

span()等等。

使用正则表达式对象

• 使用使用re模块的compile()方法将正则表达式编译生成

正则表达式对象,编译后的正则表达式对象可以提高字符

串处理速度

• 使用正则表达式对象提供的方法进行字符串处理

•match(string[, pos[, endpos]]):在字符串开头或指定

位置进行搜索,模式必须出现在字符串开头或指定位置

•search(string[, pos[, endpos]]):搜索;

•findall(string[, pos[, endpos]]):在字符串中查找所

有符合正则表达式的字符串列表。

第5章 函数设计与使用

• 将可能需要反复执行的代码封装为函数,

• 在需要该段代码功能的地方调用实现代码的复用

• 保证代码的一致性

• 修改函数代码所有调用均受到影响

5.2 形参与实参

• 函数定义时括弧内为形参,一个函数可以没有形参,但是括

弧必须要有,表示该函数不接受参数

• 函数调用时向其传递实参,将实参的值或引用传递给形参

• 在函数内直接修改形参的值不影响实参

如果传递给函数的是Python的可变序列,并且在函数内部使用下标或其他方式为可变序列增加、删除元素或修改元素值时,修改后的结果时可以反映到函数之外的,即实参也得到相应的修改。

5.3 参数类型

• Python函数参数类型:普通参数、默认值参数、关键参数、

可变长度参数等等。

• Python定义函数时不需要指定参数的类型,也不需要指定函

数的类型,完全由调用者决定,类似于重载和泛型

• 函数编写如果有问题,只有在调用时才能被发现,传递某些

参数时执行正确,而传递另一些类型的参数时则出现错误

默认值参数

def 函数名(形参名=默认值,……)

函数体

默认值参数必须出现在函数参数列表的最右端

任何一个默认值参数右边不能有非默认值参数

• 多次调用函数并且不为默认值参数传递值时,默认值参数只在第一次调用时进行解释。

关键参数

• 关键参数:调用函数时的传递参数的方式

通过关键参数传递,实参顺序可以和形参顺序不一致

可变长度参数

两种形式:*parameter和**parameter

前者用来接收任意多个实参并将其放在一个元组中,后者接收类似于关键参数一样显示赋值形式的多个实参并将其放入字典中。

参数传递时的序列解包

在实参名称前加一个星号,Python解释器将自动进行解包,然后传递给多个单变量形参。

def demo(a,b,c):
    print(a+b+c)
seq=[1,2,3]
demo(*seq)
tup=(1,2,3)
demo(*tup)
set1=&#123;1,2,3&#125;
demo(*set1)
dic=&#123;1:'a',2:'b',3:'c'&#125;
demo(*dic.values())

5.4 return语句

• 从一个函数中返回,即跳出函数

• 从函数中返回一个值

• 没有return语句,Python以return None结束

5.5 变量作用域

  1. 一个变量已在函数外定义,如果在函数内需要修改这个变量的值,并将这个赋值结果反映到函数之外,可以在函数内用global声明这个变量为全局变量。
  2. 在函数内部直接使用global关键字将一个变量声明为全局变量,即使在函数外没有定义该全局变量,在调用这个函数之后,将自动增加新的全局变量。

5.6 lambda表达式

• 可以用来声明匿名函数,即没有函数名字的临时使用的小函数

• 只可以包含一个表达式,且该表达式的计算结果为函数的返回值

• 不允许包含其他复杂的语句,但在表达式中可以调用其他函数

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

def demo(n):
    return n*n
a_list=[1,2,3,4,5]
list(map(lambda x:demo(x),a_list))
#[1,4,9,16,25]
data=[4,6,29,10,5]
data.sort(key=lambda x:len(str(x)),reverse=True)

在使用lambda表达式,要注意变量作用域带来的问题,在下面的代码中变量x是在外部作用域中定义的,对lambda表达式而言不是局部变量,从而导致出现了错误。

r=[]
for x in range(10):
    r.append(lambda n=x:n**2) #换名

5.8 高级话题

  • 内置函数map:将一个函数作用到一个序列或迭代器对象上,并返回一个map对象作为结果,该函数不对原序列或迭代器对象做任何修改

  • reduce()可以将一个接受2个参数的函数以累积的方式从左到右依次作用到一个序列或迭代器对象的所有元素上。

from functools import reduce
seq=[1,2,3,4]
reduce(lambda x,y:x+y,seq)

def add(x,y):
    return x+y
reduce(add,range(10))
  • filter()

    将一个函数作用到一个序列上,返回该序列中使得该函数返回值为True的那些元素组成的列表、元组或字符串。

    seq=['foo','x41','?!']
    def func(x):
        return x.isalnum()
    list(filter(func,seq))
    #['foo','x41']
    
  • yield()

    Yield语句创建生成器:惰性求值,可迭代(适用于大数据处理)

def f():
    a,b=1,1
    while True:
        yield a
        a,b=b,a+b
a=f()
for i in range(10):
    print(a.__next__(),end=' ')

第6章 面向对象程序设计

面向对象程序设计:合理地定义和组织类以及类之间的关系

• Python真正面向对象的高级动态编程语言

• Python完全支持面向对象的基本功能:

封装、继承、多态以及对基类方法的覆盖或重写

• Python对象的概念广泛,一切皆对象

• Python对象不一定必须是某个类的实例:

字符串、列表、字典、元组等内置数据类型

• 类的成员:

成员属性:用变量形式表示的对象

成员方法:用函数形式表示的对象

类的定义与使用

• Python类定义

• class关键字+空格+类名+冒号

• 类名的首字母一般要大写

class Car:

def infor(self):

print(“ This is a car “)

• 类用来实例化对象,通过“对象名.成员” 访问数据和成员

>>> car = Car()

>>> car.infor()

This is a car

• 使用内置方法isinstance()来测试对象是否为某个类的实例

>>> isinstance(car, Car)

True

>>> isinstance(car, str)

False

• Python关键字“pass”

• 类似于空语句,使用该关键字来“占位”

• 在类和函数的定义中或者选择结构中为软件升级预留空间

>>> class A:

pass

>>> def demo():

pass

>>> if 5>3:

pass

self参数

• 类的所有实例方法都必须至少有一个 “self”的参数

• “self”参数必须是方法的第一个形参

• “self”参数代表将来要创建的对象本身

• 在类的实例方法中访问实例属性时需要以“self”为前缀

• 在类外部用对象名调用对象方法时并不需要传递self参数

• 在类外部通过类名调用对象方法需要显式为self参数传值

类成员与实例成员

• 类成员:指数据成员,或者广义上的属性

• 属性有两种,一种是实例属性,另一种是类属性

• 实例属性

• 一般在构造函数__init__()中定义,使用时以self作为前缀

• 实例属性属于实例(对象),只能通过对象名访问

• 类属性

• 在类中所有方法之外定义的数据成员

• 类属性属于类,可以通过类名或对象名访问

• 类的方法中可调用类本身的其他方法,可访问类和对象属性

Python中可以动态地为类和对象增加成员

私有成员与公有成员

• 定义类的属性时,如果属性名以两个下划线“__”开头则

表示是私有属性,否则是公有属性。

• 私有属性是为了数据封装和保密而设的属性,一般只能在

类的成员方法(类的内部)中使用访问,在类的外部不能

直接访问,需要通过调用对象的公有成员方法来访问

• 公有属性是可以公开使用的,既可以在类的内部进行访问,

也可以在外部程序中使用。

• Python提供了访问私有属性的特殊方式,可用于程序的测

试和调试,对于成员方法也具有同样的性质。

_xxx:保护成员

__ xxx __:系统定义的特殊成员

__ xxx: 类中的私有成员

在对象外部可以通过“对象名._类名 __ xxx”访问

方法

• 公有方法

属于对象,可以访问属于类和对象的成员,公有方法通过对象名直接调

用,通过类名来调用属于对象的公有方法,需要显式为该方法 “self”

参数传递一个对象名,用来确定访问哪个对象的数据成员

• 私有方法

属于对象,私有方法的名字以两个下划线“__”开始,可以访问属于类

和对象的成员,私有方法在属于对象的方法中通过“self”调用或在外部

通过Python支持的特殊方式来调用

• 静态方法

通过类名和对象名调用,不能直接访问属于对象的成员,只能访问属于类的成员

• 类方法

通过类名和对象名调用,不能直接访问属于对象的成员,只能访问属于类的成员,一般将“cls”作为类方法的第一个参数名称,但也可以使用其他的名字作为参数,并且在调用类方法时不需要为“cls”参数传递值

属性

• 使用@property或property()声明属性

• Python 2.x和Python 3.x对属性的实现和处理方式

不一样,内部实现有较大的差异

• Python 2.x为对象新增数据成员隐藏同名已有属性

• Python 3.x属性实现完整,支持更全面的保护机制

类常用特殊方法

• Python中类的构造函数是__init__()

一般用来为数据成员设置初值或进行其他必要的初始化工作,

在创建对象时被自动调用和执行,可以通过为构造函数定义

默认值参数来实现类似于其他语言中构造函数重载的目的。

如果用户没有设计构造函数,Python将提供一个默认的构造

函数用来进行必要的初始化工作。

• Python中类的析构函数是__del__()

一般用来释放对象占用的资源,在Python删除对象和收回对

象空间时被自动调用和执行。如果用户没有编写析构函数,

Python将提供一个默认的析构函数进行必要的清理工作。

• 其他方法

继承机制

• 继承的目的是代码复用和设计复用

• 继承关系中,已有的、设计好的类称为父类或基类,新设计的类称为子类或派生类

• 派生类可以继承父类的公有成员,但不能继承其私有成员

• 在派生类中调用基类的方法,可以使用内置函数super()或者通过“基类名.方法名()”的方式实现

• Python支持多继承,如果父类中有相同的方法名,而在子类中使用时没有指定父类名,则Python解释器将从左向右按顺序进行搜索

Math库

  1. log(x,a) 如果不指定a,则默认以e为基数,a参数给定时,将 x 以a为底的对数返回。
    >>> math.log(math.e)
    1.0
    >>> math.log(32,2)
    5.0
    >>>

  2. 大于等于x的最小的整数值,如果x是一个整数,则返回x
    >>> math.ceil(4.12)
    5

  3. pow()返回x的y次方,即x**y
    >>> math.pow(3,4)
    81.0

  4. floor()取小于等于x的最大的整数值,如果x是一个整数,则返回自身
    >>> math.floor(4.999)
    4


文章作者: Yifan-Vincent
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Yifan-Vincent !
  目录