语言基础
变量、运算符和表达式
内置对象
•对象是python语言中最基本的概念,在python中处理的一切都是对象。
•内置对象可直接使用,python中有许多内置对象可供编程者使用,如数字、字符串、列表、del等。需要导入模块才能使用
•非内置对象需要导入模块才能使用,如正弦函数sin(x) (import math),随机数产生函数random( ) (import random)等。
•内置函数
标识符与变量
▪在Python中,不需要事先声明变量名及其类型,直接赋值即可创建各种类型的对象变量。这一点适用于Python任意类型的对象。
例如语句
>>> x = 3
创建了整型变量x,并赋值为3
再例如语句
>>> x = 'Hello world.'
创建了字符串变量x,并赋值为'Hello world.'。
赋值语句的执行过程是:
◆首先,把等号右侧表达式的值计算出来,
◆然后,在内存中寻找一个位置把值存放进去,
◆最后,创建变量并指向这个内存地址。
>>> x = 3
•Python中的变量并不直接存储值
•而是存储了值的内存地址或者引用——这也是变量类型随时可以改变的原因。
▪在Python中,允许多个变量指向同一个值
Python采用的是基于值的内存管理方式,
▪如果为不同变量赋值为相同值
▪这个值在内存中只有一份,多个变量指向同一块内存地址。
Python属于强类型编程语言,Python解释器会根据赋值或运算来自动推断变量类型。Python还是一种动态类型语言,变量的类型也是可以随时变化的。
变量名命名规范:
✓变量名必须以字母或下划线开头,但以下划线开头的变量在Python中有特殊含义;
✓变量名中不能有空格以及标点符号(括号、引号、逗号、斜线、反斜线、冒号、句号、问号等等);
✓不能使用关键字作变量名,可以导入keyword模块后使用print(keyword.kwlist)查看所有Python关键字;
✓变量名对英文字母的大小写敏感,例如student和Student是不同的变量。
✓不建议使用系统内置的模块名、类型名或函数名以及已导入的模块名及其成员名作变量名,这将会改变其类型和含义,可以通过dir(__builtins__)查看所有内置模块、类型和函数;
数据类型—数字
•Python支持任意大的数字,具体可以大到什么程度仅受内存大小的限制。由于精度的问题,对于实数运算可能会有一定的误差,
◆应尽量避免在实数之间直接进行相等性测试,
◆而是应该以二者之差的绝对值是否足够小作为两个实数是否相等的依据。
•在数字的算术运算表达式求值时会进行隐式的类型转换,
◆如果存在复数则都变成复数
◆如果没有复数但是有实数就都变成实数
◆如果都是整数则不进行类型转换。
▪Python内置支持复数类型及其运算,并且形式与数学上的复数完全一致。
▪Python 3.6.x支持在数字中间位置使用单个下划线作为分隔来提高数字的可读性,类似于数学上使用逗号作为千位分隔符。
▪在Python数字中单个下划线可以出现在中间任意位置
但不能出现开头和结尾位置
也不能使用多个连续的下划线。
数据类型
字符串与字节串
•在Python中,没有字符常量和变量的概念,只有字符串类型的常量和变量,单个字符也是字符串。
•使用单引号、双引号、三单引号、三双引号作为定界符(delimiter)来表示字符串,并且不同的定界符之间可以互相嵌套,最外层有效。
•Python 3.x全面支持中文,中文和英文字母都作为一个字符对待,甚至可以使用中文作为变量名。
•除了支持使用加号运算符连接字符串以外,Python字符串还提供了大量的方法支持格式化、查找、替换、排版等操作。
>>> x = 'Hello world.' #使用单引号作为定界符
>>> x = "Python is a great language." #使用双引号作为定界符
>>> x = '''Tom said, "Let's go."''' #不同定界符之间可以互相嵌套
>>> print(x)Tom said, "Let's go."
>>> x = ‘good ’ + ‘morning’ #连接字符串,常量、变量皆可
>>> x'good morning'
>>> x = 'good ''morning' #连接字符串,仅适用于字符串常量
>>> x'good morning'
▪对str类型的字符串调用其encode()方法进行编码得到bytes字节串,对bytes字节串调用其decode()方法并指定正确的编码格式则得到str字符串。
>>> type('Hello world') #默认字符串类型为str<class 'str'>
>>> type(b'Hello world') #在定界符前加上字母b表示字节串<class 'bytes'>
>>> 'Hello world'.encode('utf8') #使用utf8编码格式进行编码b'Hello world'
>>> 'Hello world'.encode('gbk') #使用gbk编码格式进行编码b'Hello world'
>>> '烟台大学'.encode('utf8') #对中文进行编码
b'\xe7\x83\x9f\xe5\x8f\xb0\xe5\xa4\xa7\xe5\xad\xa6'
>>> _.decode('utf8') #一个下划线表示最后一次正确输出结果'烟台大学'
>>> '烟台大学'.encode('gbk')
b'\xd1\xcc\xcc\xa8\xb4\xf3\xd1\xa7'
>>> _.decode('gbk') #对bytes字节串进行解码'烟台大学'
列表、元组、字典、集合
>>> x_list= [1, 2, 3] #创建列表对象
>>> x_tuple= (1, 2, 3) #创建元组对象
>>> x_dict= {'a':97, 'b':98, 'c':99} #创建字典对象
>>> x_set= {1, 2, 3} #创建集合对象
>>> print(x_list[1]) #使用下标访问指定位置的元素2
>>> print(x_tuple[1]) #元组也支持使用序号作为下标2
>>> print(x_dict['a']) #字典对象的下标是“键”97
>>> 3 in x_set #成员测试True22
序列的访问
运算符和表达式
•在Python中,单个常量或变量可以看作最简单的表达式,使用除赋值运算符之外的其他任意运算符和函数调用连接的式子也属于表达式。
•运算符优先级遵循的规则为:算术运算符优先级最高,其次是位运算符、成员测试运算符、关系运算符、逻辑运算符等,算术运算符遵循“先乘除,后加减”的基本运算原则。
•虽然Python运算符有一套严格的优先级规则,但是强烈建议在编写复杂表达式时使用圆括号来明确说明其中的逻辑来提高代码可读性。
算术运算符
1)+ 运算符除了用于算术加法以外还可用于列表、元组、字符串的连接,但不支持不同类型的对象之间相加或连接。
>>> [1, 2, 3] + [4, 5, 6] #连接两个列表[1, 2, 3, 4, 5, 6]
>>> (1, 2, 3) + (4,) #连接两个元组(1, 2, 3, 4)
>>> 'abcd' + '1234' #连接两个字符串'abcd1234'
>>> 'A' + 1 #不支持字符与数字相加,抛出异常TypeError: Can't convert 'int' object to str implicitly
>>> True + 3 #Python内部把True当作1处理4
>>> False + 3 #把False当作0处理
2)* 运算符除了表示算术乘法,还可用于列表、元组、字符串这几个序列类型与整数的乘法,表示序列元素的若干次重复连接,生成新的序列对象。
字典和集合不支持与整数的相乘,因为其中的元素是不允许重复的。
>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]
>>> (1, 2, 3) * 3
(1, 2, 3, 1, 2, 3, 1, 2, 3)
>>> 'abc' * 3
'abcabcabc'
3)运算符/和//在Python中分别表示算术除法和算术求整商(向下取整)。
>>> 3 / 2 #数学意义上的除法
1.5
>>> 15 // 4 #如果两个操作数都是整数,结果为整数
3
>>> 15.0 // 4 #如果操作数中有实数,结果为实数形式的整数值
3.0
>>> -15//4 #向下取整
-4
4)% 运算符可以用于整数或实数的求余数运算
还可以用于字符串格式化,但是这种用法并不推荐。
>>> 789 % 23 #余数
7
>>> 123.45 % 3.2 #可以对实数进行余数运算,注意精度问题
1.849999999999996
>>> '%c, %d' % (65, 65) #把65分别格式化为字符和整数
'A, 65'
>>> '%f,%s' % (65, 65) #把65分别格式化为实数和字符串
'65.000000,65'
5)** 运算符表示幂乘:
>>> 3 ** 2 #3的2次方,等价于pow(3, 2)
9
>>> pow(3, 2, 8) #内置函数pow(x, y, z=None) #返回x的y次方,等价于x ** y或(x ** y) % z
1
>>> 9 ** 0.5 #9的0.5次方,平方根
3.0
>>> (-9) ** 0.5 #可以计算负数的平方根
(1.8369701987210297e-16+3j)
•Python关系运算符最大的特点是可以连用,其含义与我们日常的理解完全一致。使用关系运算符的一个最重要的前提是,操作数之间必须可比较大小。例如把一个字符串和一个数字进行大小比较是毫无意义的,所以Python也不支持这样的运算。
>>> 1 < 3 < 5 #等价于1 < 3 and 3 < 5
True
>>> import math
>>> math.isclose(0.4-0.1,0.3)
True
>>> 'Hello' > 'world' #比较字符串大小
False
>>> [1, 2, 3] < [1, 2, 4] #比较列表大小
True
>>> {1, 2, 3} < {1, 2, 3, 4} #测试是否子集
True
>>> {1, 2, 3} == {3, 2, 1} #测试两个集合是否相等
True
>>> {1, 2, 4} > {1, 2, 3} #集合之间的包含测试
False
成员测试运算符in
▪成员测试运算符in用于成员测试,即测试一个对象是否为另一个对象的元素如果是则返回True,否则返回False。
Python 常用内置函数
range()
▪range()是Python开发中非常常用的一个内置函数,
▪range([start,] end [, step] )
▪该函数返回惰性求值特点的range对象,其中包含左闭右开区间[start,end)内
▪以step为步长的整数。参数start默认为0,step默认为1。
▪列表推导式
用一种简单的方法创建列表,返回对象为一个符合要求的列表
[变量表达式 for 变量 in 可迭代对象 if 条件]
同一性测试运算符is
▪同一性测试运算符is用来测试两个对象是否是同一个,如果是则返回True,否则返回False。如果两个对象是同一个,二者具有相同的内存地址。
位运算符
•位运算符只能用于整数,其内部执行过程为:首先将整数转换为二进制数,然后右对齐,必要的时候左侧补0,按位进行运算,最后再把计算结果转换为十进制数字返回。
•位与运算规则为1&1=1、1&0=0&1=0&0=0,位或运算规则为1|1=1|0=0|1=1、0|0=0,位异或运算规则为1^1=0^0=0、1^0=0^1=1。
•左移位时右侧补0,每左移一位相当于乘以2;右移位时左侧补0,每右移一位相当于整除以2。
>>> 3 << 2 #把3左移2位12
>>> 3 & 7 #位与运算3
>>> 3 | 8 #位或运算11
>>> 3 ^ 5 #位异或运算6
选择循环
条件表达式
在选择和循环结构中,Python解释器将
◆条件表达式的值是False、0(或0.0、0j等)、空值None、空列表、空元组、空集合、空字典、空字符串、空range对象或其他空迭代对象等空对象认为是False
◆其他对象均认为与True等价
关系运算符
Python中的关系运算符可以连续使用,这样不仅可以减少代码量,也比较符合人类的思维方式。
•在Python语法中,条件表达式中不允许使用赋值运算符“=”,避免了误将关系运算符“==”写作赋值运算符“=”带来的麻烦。在条件表达式中使用赋值运算符“=”将抛出异常,提示语法错误。
逻辑运算符
◼逻辑运算符and、or、not常用来连接条件表达式构成更加复杂的条件表达式
◼逻辑运算符and、or具有短路求值或惰性求值的特点,可能不会对所有表达式进行求值,而是只计算必须计算的表达式的值。
◼and、or 不一定返回布尔值
•以“and”为例,对于表达式“表达式1and 表达式2”而言,如果“表达式1”的值为“False”或其他等价值时,不论“表达式2”的值是什么,整个表达式的值都是“False”,丝毫不受“表达式2”的影响,因此“表达式2”不会被计算。
•在设计包含多个条件的条件表达式时,如果能够大概预测不同条件失败的概率,并将多个条件根据“and”和“or”运算符的短路求值特性来组织顺序,可以大幅度提高程序运行效率。
◆and、or具有短路求值(惰性求值)的特点,当连接多个表达式时只计算必须要计算的值。
>>> 3>5 and a>3 #注意,此时并没有定义变量a
False
>>> 3>5 or a>3 #3>5的值为False,所以需要计算后面表达式
NameError: name 'a' is not defined
>>> 3<5 or a>3 #3<5的值为True,不需要计算后面表达式
True
>>> 3 and 5 #最后一个计算的表达式的值作为整个表达式的值
5
>>> 3 and 5>2
True
在编写复杂条件表达式时充分利用这个特点,合理安排不同条件的先后顺序,在一定程度上可以提高代码运行速度。
另外要注意的是,运算符and、or并不一定会返回True或False,而是得到最后一个被计算的表达式的值,但是运算符not一定会返回True或False。
++、--
· Python不支持++和--运算符,虽然在形式上有时候似乎可以这样用,但实际上是另外的含义,要注意和其他语言的区别。
复合赋值运算符
•Python还有赋值运算符=和+=、-=、*=、/=、//=、**=、|=、^=等大量复合赋值运算符。例如,x+= 3在语法上等价(注意,在功能的细节上可能会稍有区别)于x = x + 3。
Python关键字简要说明
•Python关键字只允许用来表达特定的语义
◆不允许通过任何方式改变它们的含义
◆不能用来做变量名、函数名或类名等标识符。
•在Python开发环境中导入模块keyword之后,可以使用print(keyword.kwlist)查看所有关键字。
矩阵乘法运算符@
▪从Python3.5开始增加了一个新的矩阵相乘运算符@,不过由于Python没有内置的矩阵类型,所以该运算符常与扩展库numpy一起使用。
分支结构—常见的分支结构
单分支选择结构
if 表达式:
语句块
双分支选择结构
•Python还提供了一个三元运算符,并且在三元运算符构成的表达式中还可以嵌套三元运算符,可以实现与选择结构相似的效果。
语法为
value1 if condition else value2
•当条件表达式condition的值与True等价时,表达式的值为value1,否则表达式的值为value2。
>>> b = 6 if 5>13 else 9 #赋值运算符优先级非常低
>>> b
9
多分支选择结构
其中,关键字elif是else if的缩写。
◼问题解决:使用多分支选择结构将成绩从百分制变换到等级制。
def func(score):
if score > 100 or score < 0:
return 'wrong score.must between 0 and 100.'
elif score >= 90:
return 'A'
elif score >= 80:
return 'B'
elif score >= 70:
return 'C'
elif score >= 60:
return 'D'
else:
return 'E'
选择结构的嵌套
•问题解决:使用嵌套选择结构将成绩从百分制变换到等级制。
def func(score):
degree = 'DCBAAE'
if score > 100 or score < 0:
return 'wrong score.must between 0 and 100.'
else:
index = (score -60) // 10
if index >= 0:
return degree[index]
else:
return degree[-1]
内置函数
print()
▪内置函数print()
用于输出信息到标准控制台或指定文件,语法格式为:print(value1, value2, ...[, sep=' ', end='\n])
✓sep参数之前为需要输出的内容(可以有多个);
✓sep参数用于指定数据之间的分隔符,默认为空格;
✓end参数用于指定输出完数据之后再输出什么字符;
循环结构
•Python主要有for循环和while循环两种形式的循环结构,多个循环可以嵌套使用,并且还经常和选择结构嵌套使用来实现复杂的业务逻辑。
•while循环一般用于循环次数难以提前确定的情况,当然也可以用于循环次数确定的情况;
•for循环一般用于循环次数可以提前确定的情况,尤其适用于枚举或遍历序列或迭代对象中元素的场合。
for循环与while循环
•两种循环结构的完整语法形式分别为:
while 条件表达式:
循环体
[else:
else子句代码块]
和
for 取值in 序列或迭代对象:
循环体
[else:
else子句代码块]
对于带有else子句的循环结构
◆如果循环因为条件表达式不成立或序列遍历结束而自然结束时则执行else结构中的语句
◆如果循环是因为执行了break语句而导致循环提前结束则不会执行else中的语句。
•问题解决:输出1~100之间整数之和。
方法一:
s = 0
for i in range(1, 101):
s += i
else:
print(s)
方法二:
sum(range(1,101))
•问题解决:输出1~100之间能被7整除但不能同时被5整除的所有整数。
for i in range(1,101):
if i%7==0 and i%5!=0:
print(i)
break与continue语句
◆一旦break语句被执行,将使得break语句所属层次的循环提前结束;
◆continue语句的作用是提前结束本次循环,忽略continue之后的所有语句,提前进入下一次循环。
C内置函数
▪内置函数(BIF,built-infunctions)是Python内置对象类型之一,不需要额外导入任何模块即可直接使用,这些内置对象都封装在内置模块__builtins__之中,用C语言实现并且进行了大量优化,具有非常快的运行速度,推荐优先使用。
使用内置函数dir()可以查看所有内置函数和内置对象:
>>> dir(__builtins__)
▪使用help(函数名)可以查看某个函数的用法。
>>> help(sum)
类型转换与类型判断
▪内置函数bin( )、oct( )、hex( )用来将整数转换为二进制、八进制和十六进制形式,这三个函数都要求参数必须为整数。
▪内置函数int( )用来将其他形式的数字转换为整数,参数可以为整数、实数、分数或合法的数字字符串。
▪当参数为数字字符串时,还允许指定第二个参数base用来说明数字字符串的进制,base的取值应为0或2-36之间的整数,其中0表示按数字字符串隐含的进制进行转换。
▪内置函数float( )用来将其他类型数据转换为实数。
▪complex( )可以用来生成复数。
▪str( )则直接将其任意类型参数转换为字符串。
▪ord( )和chr( )是一对功能相反的函数,ord()用来返回单个字符的Unicode码,而chr()则用来返回Unicode编码对应的字符。
▪内置类ascii( )可以把对象转换为ASCII码表示形式,必要的时候使用转义字符来表示特定的字符。
>>> ascii('a')
"'a'"
>>> ascii('烟台市')
"'\\u70df\\u53f0\\u5e02'"
>>> eval(_) #单下划线最近一次运行结果,对字符串进行求值
'烟台市'
▪list( )、tuple( )、dict( )、set( )、frozenset( )用来把其他类型的数据转换成为列表、元组、字典、可变集合和不可变集合,或者创建空列表、空元组、空字典和空集合。
zip()
▪zip( )函数用来把多个可迭代对象中的元素压缩到一起,返回一个可迭代的zip对象,其中每个元素都是包含原来的多个可迭代对象对应位置上元素的元组,如同拉拉链一样。
>>> list(zip('abcd', [1, 2, 3])) #压缩字符串和列表
[('a', 1), ('b', 2), ('c', 3)]
>>> list(zip('123', 'abc', ',.!')) #压缩3个序列
[('1', 'a', ','), ('2', 'b', '.'), ('3', 'c', '!')]
>>> x = zip('abcd', '1234')
>>> list(x)
[('a', '1'), ('b', '2'), ('c', '3'), ('d', '4')]
最值与求和
▪max( )、min( )、sum( )这三个内置函数分别用于计算列表、元组或其他包含有限个元素的可迭代对象中所有元素最大值、最小值以及所有元素之和。
▪sum()默认(可以通过start参数来改变)支持包含数值型元素的序列或可迭代对象,max()和min()则要求序列或可迭代对象中的元素之间可比较大小。
>>> from random import randint
>>> a = [randint(1,100) for i in range(10)]
>>> print(max(a), min(a), sum(a))
>>> sum(a) / len(a)
max( )和min( )还支持default参数和key参数
◆其中default参数用来指定可迭代对象为空时默认返回的最大值或最小值
◆而key参数用来指定比较大小的依据或规则,可以是函数或lambda表达式。
>>> max(['2', '111']) #不指定排序规则
'2'
>>> max(['2', '111'], key=len) #返回最长的字符串
'111'
>>> print(max([], default=None)) #对空列表求最大值,返回空值None
None
基本输入输出
•input( )和print( )是Python的基本输入输出函数,前者用来接收用户的键盘输入,后者用来把数据以指定的格式输出到标准控制台或指定的文件对象。
•不论用户输入什么内容,input( ) 一律返回字符串对待,必要的时候可以使用内置函数int()、float()或eval()对用户输入的内容进行类型转换。
▪内置函数print()用于输出信息到标准控制台或指定文件,
语法格式为:
print(value1, value2, ..., sep=' ', end='\n', file=sys.stdout, flush=False)
✓sep参数之前为需要输出的内容(可以有多个);
✓sep参数用于指定数据之间的分隔符,默认为空格;
✓end参数用于指定输出完数据之后再输出什么字符;
✓file参数用于指定输出位置,默认为标准控制台,也可以重定向输出到文件。
print函数格式化输出
1、f’
for i,v in enumerate(a_list):
print(f’列表的第{i+1}个元素是:{v}’)
排序与逆序
▪sorted(iterable, key=None, reverse=False)对列表、元组、字典、集合或其他可迭代对象进行排序并返回排序后的新列表,key用来指定排序规则或依据,reverse用来指定升序或降序。该函数不改变iterable内任何元素的顺序
▪reversed( )对可迭代对象(生成器对象和具有惰性求值特性的zip、map、filter、enumerate等类似对象除外)进行翻转(首尾交换)并返回可迭代的reversed对象。
枚举与迭代
▪enumerate( )函数用来枚举可迭代对象中的元素,返回可迭代的enumerate对象,其中每个元素都是包含索引和值的元组。
map()
▪内置函数map( )把一个函数func依次映射到序列或迭代器对象的每个元素上,并返回一个可迭代的map对象作为结果,map对象中每个元素是原序列中元素经过函数func处理后的结果。
列表
◆列表(list)是包含若干元素的有序连续内存空间。当列表增加或删除元素时,列表对象自动进行内存的扩展或收缩,从而保证相邻元素之间没有缝隙。
◆但插入或删除非尾部元素时涉及列表中大量元素的移动,会严重影响效率。
◆除非确实有必要,否则应尽量从列表尾部进行元素的追加与删除操作。
•在形式上,列表的所有元素放在一对方括号[ ]中,相邻元素之间使用逗号分隔。
•在Python中,同一个列表中元素的数据类型可以各不相同,可以同时包含整数、实数、字符串等基本类型的元素,也可以包含列表、元组、字典、集合、函数以及其他任意对象。
•如果只有一对方括号而没有任何元素则表示空列表。
◼列表创建与删除
•使用“=”直接将一个列表赋值给变量即可创建列表对象。
>>> a_list = ['a', 'b', 'mpilgrim', 'z', 'example']
>>> a_list = [] #创建空列表
•也可以使用list( )函数把元组、range对象、字符串、字典、集合或其他可迭代对象转换为列表。
•当一个列表不再使用时,可以使用del命令将其删除,这一点适用于所有类型的Python对象。
◼列表元素访问
◆创建列表之后,可以使用整数作为下标来访问其中的元素,其中0表示第1个元素,1表示第2个元素,2表示第3个元素,以此类推;列表还支持使用负整数作为下标,其中-1表示最后1个元素,-2表示倒数第2个元素,-3表示倒数第3个元素,以此类推。
◼列表常用方法
1)append( )、insert( )、extend( )——列表扩展方法
◆append( )用于向列表尾部追加一个元素
◆insert( )用于向列表任意指定位置插入一个元素
◆extend( )用于将另一个列表中的所有元素追加至当前列表的尾部这3个方法都属于原地操作,不影响列表对象在内存中的起始地址。
(2)pop( )、remove( )、clear( )——列表删除方法
◆pop( )用于删除并返回指定位置(默认是最后一个)上的元素
◆remove( )用于删除列表中第一个值与指定值相等的元素
◆clear( )用于清空列表中的所有元素。这3个方法也属于原地操作。
另外,还可以使用del命令删除列表中指定位置的元素,同样也属于原地操作。
(3)count( )、index( )——列表统计方法
count( )用于返回列表中指定元素出现的次数
index( )用于返回指定元素在列表中首次出现的位置,如果该元素不在列表中则抛出异常。
(4)sort( )、reverse( )——sorted( ),reversed( )——列表排列方法
sort( )方法用于按照指定的规则对所有元素进行排序,原地操作。
reverse( )方法用于将列表所有元素逆序或翻转,原地操作。
◼列表支持运算符
◆加法运算符+也可以实现列表增加元素的目的,但不属于原地操作,而是返回新列表,涉及大量元素的复制,效率非常低。
◆使用复合赋值运算符+=实现列表追加元素时属于原地操作,与append()方法一样高效。
◆乘法运算符*可以用于列表和整数相乘,表示序列重复,返回新列表。
◆运算符*=也可以用于列表元素重复,属于原地操作。
•成员测试运算符in可用于测试列表中是否包含某个元素,查询时间随着列表长度的增加而线性增加,而同样的操作对于集合而言则是常数级的。
>>> 3 in [1, 2, 3]
True
>>> 3 in [1, 2, '3']
False
◼内置函数对列表的操作
•max( )、min( )函数用于返回列表中所有元素的最大值和最小值,
•sum( )函数用于返回列表中所有元素之和;
•len( )函数用于返回列表中元素个数
•zip()函数用于将多个列表中元素重新组合为元组并返回包含这些元组的zip对象;
•enumerate( )函数返回包含若干下标和值的迭代对象;
•map( )函数把函数映射到列表上的每个元素
•filter( )函数根据指定函数的返回值对列表元素进行过滤;
•all( )函数用来测试列表中是否所有元素都等价于True
•any( )用来测试列表中是否有等价于True的元素。
列表推导式
•列表推导式使用非常简洁的方式来快速生成满足特定需求的列表,代码具有非常强的可读性。
•列表推导式语法形式为:
•列表推导式在逻辑上等价于一个循环语句,只是形式上更加简洁。
例如:
切片操作
•在形式上,切片使用2个冒号分隔的3个数字来完成。
[start:end:step]
✓第一个数字start表示切片开始位置,默认为0;
✓第二个数字end表示切片截止(但不包含)位置(默认为列表长度);
✓第三个数字step表示切片的步长(默认为1)。
✓当start为0时可以省略,当end为列表长度时可以省略,当step为1时可以省略,省略步长时还可以同时省略最后一个冒号。
✓当step为负整数时,表示反向切片,这时start应该在end的右侧才行。
(1)使用切片获取列表部分元素组成的新列表
使用切片可以返回列表中部分元素组成的新列表。
与使用索引作为下标访问列表元素的方法不同,切片操作不会因为下标越界而抛出异常,而是简单地在列表尾部截断或者返回一个空列表,代码具有更强的健壮性。
(2)使用切片为列表增加元素
可以使用切片操作在列表任意位置插入新元素,不影响列表对象的内存地址,属于原地操作。
(3)使用切片替换和修改列表中的元素
(4)使用切片删除列表中的元素
元组—轻量级列表
从形式上,元组的所有元素放在一对圆括号( )中,元素之间使用逗号分隔,如果元组中只有一个元素则必须在最后增加一个逗号。
元组创建与元素访问
•很多内置函数的返回值也是包含了若干元组的可迭代对象,例如enumerate( )、zip( )等等。
元组与列表的异同点
•列表和元组都属于有序序列,都支持使用双向索引访问其中的元素
•支持统计方法:count( )方法统计指定元素的出现次数和index( )方法获取指定元素的索引
•支持len( )、map( )、filter( )等大量内置函数和+、+=、in等运算符也都可以作用于列表和元组。
•元组属于不可变(immutable)序列,不可以直接修改元组中元素的值,也无法为元组增加或删除元素。
◆不支持append( )、extend( )和insert( )等扩展方法,无法向元组中添加元素;
◆不支持remove( )、pop( )和clear( )等删除方法
◆不支持对元组元素进行del操作,不能从元组中删除元素,而只能使用del命令删除整个元组。
◆支持切片来访问元组中的元素
◆不支持切片来修改元组中元素的值
◆不支持切片来为元组增加或删除元素。
•Python的内部实现对元组做了大量优化,访问速度比列表更快。
•如果定义了一系列常量值,主要用途仅是对它们进行遍历或其他类似用途,而不需要对其元素进行任何修改,那么一般建议使用元组而不用列表。
•元组在内部实现上不允许修改其元素值,从而使得代码更加安全,例如调用函数时使用元组传递参数可以防止在函数中修改元组,而使用列表则很难保证这一点。
生成器推导式
•生成器推导式(generator expression)的用法与列表推导式非常相似,在形式上生成器推导式使用圆括号(parentheses)作为定界符,而不是列表推导式所使用的方括号(square brackets)。
•与列表推导式最大的不同是,生成器推导式的结果是一个生成器对象。生成器对象类似于迭代器对象,具有惰性求值的特点,只在需要时生成新元素,比列表推导式具有更高的效率,空间占用非常少,尤其适合大数据处理的场合。
使用生成器对象的元素时
①可以根据需要将其转化为列表或元组
②也可以使用生成器对象的__next__( )方法
③内置函数next( )进行遍历
④或者直接使用for循环来遍历其中的元素。
但是不管用哪种方法访问其元素,只能从前往后正向访问每个元素
◆没有任何方法可以再次访问已访问过的元素(每次使用类似pop(0))
◆也不支持使用下标访问其中的元素
◆当所有元素访问结束以后,如果需要重新访问其中的元素,必须重新创建该生成器对象。
•enumerate、filter、map、zip等其他迭代器对象也具有同样的特点。
▪使用生成器对象__next__()方法或内置函数next()进行遍历
•使用for循环直接迭代生成器对象中的元素
•访问过的元素不再存在
字典—反映对应关系的映射类型
•字典(dictionary)是包含若干“键:值”元素的无序可变序列
•字典中的每个元素包含用冒号分隔开的“键”和“值”两部分,表示一种映射或对应关系,也称关联数组
•定义字典时,每个元素的“键”和“值”之间用冒号分隔,不同元素之间用逗号分隔,所有的元素放在一对大括号“{}”中。
•字典中元素的“键”可以是Python中任意不可变数据,例如整数、实数、复数、字符串、元组等类型等可哈希数据
•但不能使用列表、集合、字典或其他可变类型作为字典的“键”
•“键”不允许重复
•“值”是可以重复的。
字典的创建
•使用赋值运算符“=”将一个字典赋值给一个变量即可创建一个字典变量。
>>> aDict = {'server': 'db.diveintopython3.org', 'database': 'mysql'}
•也可以使用内置类dict以不同形式创建字典。
字典元素的访问
•字典中的每个元素表示一种映射关系或对应关系
•根据提供的“键”作为下标就可以访问对应的“值”
•如果字典中不存在这个“键”会抛出异常。
•字典对象提供了一个get( )方法用来返回指定“键”对应的“值”
•并且允许指定该键不存在时返回特定的“值”。
◆使用字典对象的items( )方法可以返回字典的键、值对。
◆使用字典对象的keys( )方法可以返回字典的键。
◆使用字典对象的values( )方法可以返回字典的值。
案例1:首先生成包含1000个随机字符的字符串,然后统计每个字符的出现次数。
import string
import random
x = string.ascii_letters + string.digits+ string.punctuation
y = [random.choice(x) for i in range(1000)]
z = ''.join(y)>>> d = dict() //使用字典保存每个字符出现次数
for ch in z:d[ch] = d.get(ch, 0) + 1
元素添加、修改与删除
•当以指定“键”为下标为字典元素赋值时,有两种含义:
1)若该“键”存在,则表示修改该“键”对应的值;
2)若不存在,则表示添加一个新的“键:值”对,也就是添加一个新元素。
使用字典对象的update( )方法
•将另一个字典的“键:值”一次性全部添加到当前字典对象
•如果两个字典中存在相同的“键”,则以另一个字典中的“值”为准对当前字典进行更新。
•如果需要删除字典中指定的元素,可以使用del命令。
•也可以使用字典对象的pop( )和popitem( )方法弹出并删除指定的元素.
集合
•集合(set)属于Python无序可变序列,使用一对大括号作为定界符,元素之间使用逗号分隔,同一个集合内的每个元素都是唯一的,元素之间不允许重复。
•集合中只能包含数字、字符串、元组等不可变类型(或者说可哈希)的数据,而不能包含列表、字典、集合等可变类型的数据。
集合对象的创建与删除
•直接将集合赋值给变量即可创建一个集合对象。
>>> a = {3, 5} #创建集合对象
>>> type(a) #查看对象类型
<class 'set'>
•也可以使用函数set( )函数将列表、元组、字符串、range对象等其他可迭代对象转换为集合,如果原来的数据中存在重复元素,则在转换为集合的时候只保留一个;如果原序列或迭代对象中有不可哈希的值,无法转换成为集合,抛出异常。
>>> a_set = set(range(8, 14)) #把range对象转换为集合
>>> a_set
{8, 9, 10, 11, 12, 13}
>>> b_set = set([0, 1, 2, 3, 0, 1, 2, 3, 7, 8]) #转换时自动去掉重复元素
>>> b_set
{0, 1, 2, 3, 7, 8}
>>> x = set() #空集
集合操作与运算
(1)集合元素增加与删除
•使用集合对象的add( )方法可以增加新元素,如果该元素已存在则忽略该操作,不会抛出异常;
•update( )方法用于合并另外一个集合中的元素到当前集合中,并自动去除重复元素。
◆pop( )方法用于随机删除并返回集合中的一个元素,如果集合为空则抛出异常;
◆remove( )方法用于删除集合中的元素,如果指定元素不存在则抛出异常;
◆discard( )用于从集合中删除一个特定元素,如果元素不在集合中则忽略该操作;
◆clear( )方法清空集合删除所有元素。
(2)集合运算
应用案例
案例1:使用集合快速提取序列中单一元素,即提取出序列中所有不重复元素。如果使用传统方式的话,需要编写下面的代码:
>>> import random #生成100个介于0到9999之间的随机数
>>> listRandom = [random.choice(range(10000)) for i in range(100)]
>>> noRepeat = []
>>> for i in listRandom :
if i not in noRepeat :
noRepeat.append(i)
•而如果使用集合的话,只需要下面这么一行代码就可以了,可以参考上面的代码对结果进行验证.
>>> newSet = set(listRandom)
•案例3:推荐系统。
•假设已有若干用户名字及其喜欢的电影清单,现有某用户,已看过并喜欢一些电影,现在想找个新电影看看,又不知道看什么好。
•思路:根据已有数据,查找与该用户爱好最相似的用户,也就是看过并喜欢的电影与该用户最接近,然后从那个用户喜欢的电影中选取一个当前用户还没看过的电影,进行推荐。
from random import randrange
# 其他用户喜欢看的电影清单
data = {'user'+str(i):{'film'+str(randrange(1, 10)) for j in range(randrange(15))} for i in range(10)}
# 待测用户曾经看过并感觉不错的电影
user = {'film1', 'film2', 'film3'}
# 查找与待测用户最相似的用户和Ta喜欢看的电影
similarUser, films = max(data.items(), key=lambda item: len(item[1]&user)
print('历史数据:')
for u, f in data.items():
print(u, f, sep=':')
print('和您最相似的用户是:', similarUser)
print('Ta最喜欢看的电影是:', films)
print('Ta看过的电影中您还没看过的有:', films-user)
函数
函数定义与使用
❖函数定义语法:
def函数名([参数列表]):
'''注释'''
函数体
❖注意事项
✓括号后面的冒号必不可少
✓函数体相对于def关键字必须保持一定的空格缩进
✓函数形参、函数返回值不需要声明类型
✓即使该函数不需要接收任何参数,也必须保留一对空的圆括号
✓Python允许嵌套定义函数
•在Python中,定义函数时也不需要声明函数的返回值类型,而是使用return语句结束函数执行的同时返回任意类型的值,函数返回值类型与return语句返回表达式的类型一致。
•不论return语句出现在函数的什么位置,一旦得到执行将直接结束函数的执行。
◆函数没有return语句
◆有return语句但是没有执行到
◆执行了不返回任何值的return语句解释器都会认为该函数以return None结束,即返回空值。
•函数定义时圆括弧内是使用逗号分隔开的形参列表(parameters),函数可以有多个参数,也可以没有参数,但定义和调用时一对圆括弧必须要有。
•定义函数时不需要声明参数类型,解释器会根据实参的类型自动推断形参类型。
✓位置参数✓默认值参数✓关键字参数✓可变长度参数
函数参数
位置参数(positionalarguments)是比较常用的形式
▪调用函数时实参和形参的顺序必须严格一致
▪并且实参和形参的数量必须相同。
默认值参数
•默认值参数的函数定义语法如下:
def 函数名(......,形参名=默认值):
函数体
在调用带有默认值参数的函数时,是否为默认值参数传递实参是可选的。
◆可以不进行传值,此时函数将会直接使用函数定义时设置的默认值
◆也可以通过显式赋值来替换其默认值
•需要注意的是,在定义带有默认值参数的函数时,任何一个默认值参数右边都不能再出现没有默认值的普通位置参数,否则会提示语法错误。
•可以使用“函数名.__defaults__”随时查看函数所有默认值参数的当前值,其返回值为一个元组,其中的元素依次表示每个默认值参数的当前值。
关键字参数
•关键字参数主要指调用函数时的参数传递方式,与函数定义无关。
•通过关键参数可以按参数名字传递值,明确指定哪个值传递给哪个参数,实参顺序可以和形参顺序不一致,但不影响参数值的传递结果,避免了用户需要牢记参数位置和顺序的麻烦,使得函数的调用和参数传递更加灵活方便。
可变长度参数
◼可变长度参数主要有两种形式:
在参数名前加1个*或2个**
➢*parameter用来接受多个位置参数并将其放在一个元组中
➢**parameter接受多个关键字参数并存放到字典中
*parameter的用法
◆**parameter的用法
传递参数时的序列解包
▪传递参数时,可以通过在序列类型实参前加一个星号将其解包,然后传递给多个单变量形参。
•如果函数实参是字典,可以在前面加两个星号进行解包,等价于关键字参数。
变量作用域
▪变量起作用的代码范围称为变量的作用域,不同作用域内变量名可以相同,互不影响。
局部变量:
◆在函数内部定义的普通变量
◆只在函数内部起作用
◆当函数执行结束后,局部变量自动删除,不再可以使用。
◆局部变量的引用比全局变量速度快,应优先考虑使用。
◼全局变量可以通过关键字global来定义。这分为两种情况:
◆一个变量已在函数外定义,如果在函数内需要为这个变量赋值,并要将这个赋值结果反映到函数外,可以在函数内使用global将其声明为全局变量。
◆如果一个变量在函数外没有定义,在函数内部也可以直接将一个变量定义为全局变量,该函数执行后,函数外将增加一个新的全局变量。
•注意:在某个作用域内任意位置只要有为变量赋值的操作,该变量在这个作用域内就是局部变量,除非使用global进行了声明。
◼如果局部变量与全局变量具有相同的名字,那么该局部变量会在自己的作用域内隐藏同名的全局变量。
Lambda表达式
▪lambda表达式可以用来声明匿名函数,也就是没有函数名字的临时使用的小函数,尤其适合需要一个函数作为另一个函数参数的场合。也可以定义具名函数。
◆lambda表达式只可以包含一个表达式
◆该表达式的计算结果可以看作是函数的返回值
◆不允许包含复合语句,但在表达式中可以调用其他函数。
生成器函数
含yield语句的函数可以用来创建生成器对象,这样的函数也称生成器函数。
◆yield语句与return语句的作用相似,都是用来从函数中返回值。
◆与return语句不同的是,return语句一旦执行会立刻结束函数的运行
◆而每次执行到yield语句并返回一个值之后会暂停或挂起后面代码的执行
◆下次通过生成器对象的__next__( )方法、内置函数next( )、for循环遍历生成器对象元素或其他方式显式“索要”数据时恢复执行。
◆生成器具有惰性求值的特点,适合大数据处理。
模块
import 模块名[as 别名]
from 模块名import 对象名[ as 别名]
from 模块名import *
应用案例
•案例1
编写函数,接收任意多个实数,返回一个元组,其中第一个元素为所有参数的平均值,其他元素为所有参数中大于平均值的实数。
•案例2
编写函数,接收包含n个整数的列表lst和一个整数k(0<=k<n)作为参数,返回新列表。处理规则为:将列表lst中下标k之前的元素逆序,下标k之后的元素逆序,下标K元素位置不变。
l=[12,3,18,1,2,8,10,11,-1,-2,9,7]
print(demo(l,5))
结果:[2, 1, 18, 3, 12, 8, 7, 9, -2, -1, 11, 10]
字符串
在Python中,字符串属于不可变、有序序列(不可变——元组)
•使用单引号、双引号、三单引号或三双引号作为定界符
•并且不同的定界符之间可以互相嵌套。
•除了支持序列通用方法
•双向索引、比较大小、计算长度、元素访问、切片、成员测试等操作
•字符串类型还支持一些特有的操作方法
•字符串格式化、查找、替换、排版等等。
•不能直接对字符串对象进行元素增加、修改与删除等操作
•切片操作也只能访问其中的元素而不能修改字符串中的字符。
1.字符串编码格式
•除了支持Unicode编码的str类型之外,Python还支持字节串类型bytes
•str类型字符串可以通过encode( )方法使用指定编码格式编码成为bytes对象
•bytes对象可以通过decode( )方法使用指定编码格式解码成为str类型字符串。
最早的字符串编码是美国标准信息交换码ASCII
◆仅对10个数字、26个大写英文字母、26个小写英文字母及一些其他符号进行了编码
◆ASCII码采用1个字节来对字符进行编码,最多只能表示256个符号。
•GB2312是我国制定的中文编码,使用1个字节表示英语,2个字节表示中文;GBK是GB2312的扩充
•而CP936是微软在GBK基础上开发的编码方式
•GB2312、GBK和CP936都是使用2个字节表示中文。
•UTF-8对全世界所有国家需要用到的字符进行了编码,以1个字节表示英语字符(兼容ASCII),以3个字节表示中文,还有些语言的符号使用2个字节
(例如俄语和希腊语符号)或4个字节。
•不同编码格式之间相差很大,采用不同的编码格式意味着不同的表示和存储形式,把同一字符存入文件时,写入的内容可能会不同,在试图理解其内容时必须了解编码规则并进行正确的解码。如果解码方法不正确就无法还原信息,从这个角度来讲,字符串编码也具有加密的效果。
◼Python 3.x完全支持中文字符,默认使用UTF8编码格式,无论是一个数字、英文字母,还是一个汉字,在统计字符串长度时都按一个字符对待和处理。
2.转义符与原始字符串
•为了避免对字符串中的转义字符进行转义,可以使用原始字符串,在字符串前面加上字母r或R表示原始字符串,其中的所有字符都表示原始的含义而不会进行任何转义。
3.字符串格式化
使用%运算符进行格式化
使用format方法进行格式化
格式化的字符串常量
•从Python3.6.x开始支持一种新的字符串格式化方式,官方叫做Formatted String Literals(f-string,字面量格式化字符串),在字符串前加字母f,含义与字符串对象format()方法类似。
4.字符串常用操作
•Python字符串对象提供了大量方法用于字符串的切分、连接、替换和排版等操作
•另外还有大量内置函数和运算符也支持对字符串的操作。
•字符串对象是不可变的
•所以字符串对象提供的涉及到字符串“修改”的方法都是返回修改后的新字符串,并不对原始字符串做任何修改,无一例外。
查找方法find()、rfind()
find( )、rfind( )方法分别用来返回子字符串在当前字符串指定范围(默认是整个字符串)中首次和最后一次出现的位置,如果不存在则返回-1;
查找方法index()、rindex(),统计方法count()
index( )、rindex( )方法分别用来返回子字符串在当前字符串指定范围(默认是整个字符串)中首次和最后一次出现的位置,如果不存在则抛出异常;
count( )方法用来返回子字符串在当前字符串中出现的次数。
分割方法split()、rsplit()
split( )和rsplit( )方法分别用来以指定字符串为分隔符,把当前字符串从左往右或从右往左分隔成多个字符串,并返回包含分隔结果的列表。
split( )和rsplit( )方法允许通过第二参数指定最大分割次数。
对于split( )和rsplit( )方法,如果不指定分隔符或者指定None
◆字符串中的任何空白符号(空格、换行符、制表符等)都将被当做分隔符
◆此时连续多个空白字符(哪怕类型不同)将被看做为一个分隔符。
◆split( )和rsplit( )方法明确指定使用的分隔符
分割方法partition()、rpartition()
partition( )和rpartition( )方法用来以指定字符串为分隔符将原字符串分隔为3部分:分隔符前的字符串、分隔符字符串、分隔符后的字符串,并返回包含分隔结果的元组。如果指定的分隔符不在原字符串中,则返回原字符串和两个空字符串。
连接方法join()
大小写方法lower()、upper()、capitalize()、title()、swapcase()
lower( )、upper( )、capitalize( )、title( )、swapcase( )
>>> s = "What is Your Name?"
>>> s.lower() #返回全小写字符串
'what is your name?'
>>> s.upper() #返回全大写字符串
'WHAT IS YOUR NAME?'
>>> s.capitalize() #返回首字符大写字符串
'What is your name?'
>>> s.title() #返回每个单词的首字母大写字符串
'What Is Your Name?'
>>> s.swapcase() #返回大小写互换字符串
'wHAT IS yOUR nAME?'
查找替换方法replace()
查找替换方法replace( ),类似于Word中的“全部替换”功能。
翻译方法maketrans()、translate()
maketrans()方法用来生成字符映射表
translate()方法用来根据映射表中定义的对应关系转换字符串并返回结果字符串。
问题:凯撒加密,每个字母替换为后面第k个。
>>> import string
>>> def kaisa(s, k):
lower = string.ascii_lowercase #小写字母
upper = string.ascii_uppercase #大写字母
before = string.ascii_letters
after = lower[k:] + lower[:k] + upper[k:] + upper[:k]
table = ''.maketrans(before, after) #创建映射表
return s.translate(table)
>>> s = "Python is a greate programming language. I like it!"
>>> kaisa(s, 3)
'Sbwkrq lv d juhdwh surjudpplqj odqjxdjh. L olnh lw!
删除方法strip()、rstrip()、lstrip()
◼这三个函数的参数指定的字符串并不作为一个整体对待,而是在原字符串的两侧、右侧、左侧删除参数字符串中包含的所有字符,一层一层地从外往里扒。
测试方法
startswith()、endswith()方法判断字符串是否以指定字符串开始或结束
isalnum( )、isalpha( )、isdigit( )、isnumeric( )、isspace( )、isupper( )、islower( ),用来测试字符串是否为数字或字母、是否为字母、是否为数字字符、是否为空白字符、是否为大写字母以及是否为小写字母。
对齐方法
center( )、ljust( )、rjust( ),返回指定宽度的新字符串,原字符串居中、左对齐或右对齐出现在新字符串中,如果指定宽度大于字符串长度,则使用指定的字符(默认为空格)进行填充。
zfill( )返回指定宽度的字符串,在左侧以字符0进行填充。
字符串对象支持的运算符
加法运算符,表示两个字符串连接,生成新字符串。
>>> 'hello ' + 'world'
'hello world'
成员判断,关键字in
乘法运算符,表示字符若干次重复后连接,生成新字符串。
适用于字符串对象的内置函数
•内置函数eval( )用来把任意字符串转化为Python表达式并进行求值。
字符串对象的切片操作
•切片也适用于字符串,但仅限于读取其中的元素,不支持字符串修改。
5.字符串常量
◼Python标准库string中定义数字字符、标点符号、英文字母、大写字母、小写字母等常量。
科学计算Numpy与Scipy
▪用于数据分析、科学计算与可视化的扩展模块主要有:statistics、numpy、scipy、pandas、SymPy、matplotlib、Traits、TraitsUI、Chaco、TVTK、Mayavi、VPython、OpenCV。
▪numpy:科学计算包,支持N维数组运算、处理大型矩阵、成熟的广播函数库、矢量运算、线性代数、傅里叶变换、随机数生成,并可与C++/Fortran语言无缝结合。
▪树莓派Python v3默认安装已经包含了numpy。
▪scipy:scipy依赖于numpy,提供了更多的数学工具,包括矩阵运算、线性方程组求解、积分、优化、插值、信号处理、图像处理、统计等等。
▪matplotlib模块依赖于numpy模块和tkinter模块,可以绘制多种形式的图形,包括线图、直方图、饼状图、散点图、误差线图等等,图形质量可满足出版要求,是数据可视化的重要工具。
▪pandas(PythonData Analysis Library)是基于numpy的数据分析模块,提供了大量标准数据模型和高效操作大型数据集所需要的工具,可以说pandas是使得Python能够成为高效且强大的数据分析环境的重要因素之一。
numpy
◆数组生成方法
1)array( )方法可以将一个可迭代对象转化为数组(array)
2)arange( )方法类似于内置函数range( ) (左闭右开),可以生成一个有规律的数组。
3)linsapce(start,stop, num=50)生成一个确定个数的等差数列(左闭右闭)构成的数组。
4)logspace(start, stop, num=50, endpoint=True, base=10.0)生成一个确定个数的等差数列(左闭右闭)为指数、base为底数构成的数组。
5)ones( )方法和zeros( )方法用于生成全1和全0的数组。
6)identity( )方法用于生成单位矩阵。
7)empty ( )方法空数组,只申请空间而不初始化,元素值是不确定的。
8)randint( )方法可以在指定范围内生成一个指定个数的数组。
9)rand( )方法可以在[0, 1)内生成一个指定个数的数组。
10)standard_normal( )方法可以在从标准正态分布中随机采样生成一个指定个数的数组。
11)diag( )方法可以根据可迭代对象里的元素生成一个对角矩阵。
◆数组修改方法
1)append( )方法可以 以的方式将元素/可迭代对象扩展数组。
2)insert( )方法可以以返回新数组的方式将元素/可迭代对象插入数组。
3)repeat( )方法可以以返回新数组的方式重复数组。(区别*)
4)put( )方法可以以原地修改的方式修改数组元素。
5)+=方法可以以 的方式修改数组。
6)=+方法可以以 的方式修改数组。
◆数组与数值的运算
数组与数值的运算以 的方式将数组中的每个元素与数值进行运算。
维度相同时,数组与数值的运算以返回新数组的方式将数组中的每个元素与另一数组的对应位置的元素进行运算。
◆数组与数组的运算
◆数组转置方法
方法可以以返回新数组的方式将多维数组转置。
T方法对一维数组无效。
◆数组访问方法
1)下标访问
2)下标访问赋值
◆数组排序方法
argsort( )方法对一维数组排序,返回排序结果的索引组成的数组。
argsort( )方法依据axis参数对二维数组进行行/列排序,返回排序结果的索引组成的数组。
sort( )方法对一维数组原地排序。
sort( )方法对依据axis参数对二维数组进行原地行/列排序。
◆数组内积方法
dot( )方法可以计算并返回为数组的内积。——一维与一维
dot( )方法可以计算并返回为数组的内积。一维与二维
◆数组函数运算
round( )方法可以对数组中的所有元素进行四舍五入操作。
floor( )方法可以对数组中的所有元素进行下取整操作。
ceil( )方法可以对数组中的所有元素进行上取整操作。
square( )方法可以对数组中的所有元素进行平方操作。
sqrt( )方法可以对数组中的所有元素进行开平方操作。
sin( )方法可以对数组中的所有元素进行求正弦操作。
cos( )方法可以对数组中的所有元素进行求余弦操作。
absolute( )方法可以对数组中的所有元素进行取绝对值操作。
log2( )方法可以对数组中的所有元素求以2为底的对数。
log10( )方法可以对数组中的所有元素求以10为底的对数。
add( ), subtract( ), multiply( ), divide( )方法可以对两个可迭代对象的对应元素或可迭代对象的每个元素与数值进行加减乘除操作。
◆矩阵运算方法
创建:
matrix( )方法可以将可迭代对象矩阵化。
T, shape, size分别表示矩阵对象的转置矩阵、矩阵形状、元素个数。
变形方法:
reshape( )方法可以将矩阵或数组的形状进行改变。
运算方法:
mean( ), sum( ), max( ), min( )可以分别求出矩阵所有元素的平均值、总和、最大值、最小值。
diagonal( )方法返回由矩阵对角线元素组成的矩阵。
flatten( )方法返回由原矩阵平铺后得到的矩阵。
argsort( )方法对矩阵排序,返回排序结果的索引组成的矩阵。
sort( )方法对矩阵进行原地排序
linalg.inv( )方法可以求出目标矩阵的逆矩阵。
std( ), var( )方法可以分别求出目标矩阵的标准差、方差。
linalg.eig( ), cov( )方法可以分别求出目标矩阵的特征值和特征向量、协方差。
#计算用户u1和u2的欧氏距离
dist= np.sqrt(np.sum(np.square(rating_matrix[0,:]-rating_matrix[1,:])))
print(dist)
import pandas as pd
from sklearn.metrics.pairwiseimport euclidean_distances
dist=euclidean_distances(rating_matrix)
dist_df=pd.DataFrame(dist,columns=users,index=users)
print(dist_df)
数据可视化
matplotlib
▪matplotlib模块依赖于numpy模块和tkinter模块,可以绘制多种形式的图形,包括线图、直方图、饼状图、散点图、误差线图等等,图形质量可满足出版要求,是数据可视化的重要工具。
绘图方法
scatter( )
plot( )
pl.scatter( )
pl.plot( )
plt.pie( )
plt.plot( )
plt.subplot( )
数据分析
数据分析模块pandas
pandas(PythonData Analysis Library)是基于numpy的数据分析模块,提供了大量标准数据模型和高效操作大型数据集所需要的工具,可以说pandas是使得Python能够成为高效且强大的数据分析环境的重要因素之一。
pandas主要提供了3种数据结构:
▪1)Series,带标签的一维数组;
▪2)DataFrame,带标签且大小可变的二维表格结构;
▪3)Panel,带标签且大小可变的三维数组。
文件内容操作
◼文件操作基本知识
▪按文件中数据的组织形式把文件分为文本文件和二进制文件两类。
✓文本文件:文本文件存储的是常规字符串,由若干文本行组成,通常每行以换行符'\n'结尾。常规字符串是指记事本或其他文本编辑器能正常显示、编辑并且人类能够直接阅读和理解的字符串,如英文字母、汉字、数字字符串。文本文件可以使用字处理软件如gedit、记事本进行编辑。
✓二进制文件:二进制文件把对象内容以字节串(bytes)进行存储,无法用记事本或其他普通字处理软件直接进行编辑,通常也无法被人类直接阅读和理解,需要使用专门的软件进行解码后读取、显示、修改或执行。常见的如图形图像文件、音视频文件、可执行文件、资源文件、各种数据库文件、各类office文档等都属于二进制文件。
▪无论是文本文件还是二进制文件,文件内容操作三部曲
◆首先打开文件并创建文件对象。
◆然后通过该文件对象对文件内容进行读取、写入、删除、修改等操作。
◆最后关闭并保存文件内容。
内置函数open()
open(file, mode='r', buffering=-1, encoding=None, errors=None,newline=None, closefd=True, opener=None)
◆file:指定了被打开的文件名称。
◆mode:指定了打开文件后的处理方式。
◆buffering:指定了读写文件的缓存模式。0表示不缓存,1表示缓存,如大于1则表示缓冲区的大小。默认值是缓存模式。
◆encoding:指定对文本进行编码和解码的方式,只适用于文本模式,可以使用Python支持的任何格式,如GBK、UTF-8、CP936等等。Windows操作系统下默认编码CP936
◆r:以读模式打开一个本文文件。文件指针的初始位置位于文件头。这是open默认模式。文件不存在,如果文件不存在则抛出异常
◆w:以写模式打开一个本文文件。如果该文件已存在,则将其覆盖;如果该文件不存在,则创建新文件。
◆a:以追加模式打开一个文件。如果文件已存在,文件指针的初始位置位于文件尾,写入内容将会被追加到已有的内容之后;如果该文件不存在,则创建新文件可用于写入。不允许读操作。
◆rb:以读模式打开一个二进制文件。文件指针的初始位置位于文件头。
◆wb:以写模式打开一个二进制文件。如果该文件已存在,则将其覆盖;如果该文件不存在,则创建新文件。
◆r+:以读写模式打开一个文本文件。文件指针的初始位置位于文件头。直接写入会覆盖文件开头的内容。
◆w+:以读写模式打开一个文本文件件。如果该文件已存在,则将其覆盖。如果该文件不存在,则创建新文件。
◆a+:以读写模式打开一个文本文件。如果文件已存在,文件指针的初始位置位于文件尾,写入内容将会被追加到已有的内容之后;如果该文件不存在,则创建新文件可用于读写。
◆rb+:以读写模式打开一个二进制文件。文件指针的初始位置位于文件头。
◆wb+:以读写模式打开一个二进制文件。如果该文件已存在,则将其覆盖。如果该文件不存在,则创建新文件。
◆文件指针:随着文件读写的进行,文件指针也随着读写进程而移动。
▪如果执行正常,open()函数返回1个可迭代的文件对象(元素),通过该文件对象可以对文件进行读写操作。
▪如果指定文件不存在、访问权限不够、磁盘空间不足或其他原因导致创建文件对象失败则抛出异常。
f1 = open( 'file1.txt', 'r' ) # 以读模式打开文件
f2 = open( ‘file2.txt’, ‘w’) # 以写模式打开文件
▪当对文件内容操作完以后,一定要关闭文件对象,这样才能保证所做的任何修改都确实被保存到文件中。
f1.close()
◼文本文件内容操作
上下文管理语句with
•在实际开发中,由于文件操作场景的复杂性,常导致文件无法正常关闭导致程序无法正常运行。
•读写文件应优先考虑使用上下文管理语句with,关键字with可以自动管理资源,不论因为什么原因(哪怕是代码引发了异常)跳出with语句体
◆总能保证文件自动的被正确关闭
◆并且可以在代码块执行完毕后自动还原进入该代码块时的上下文。
•常用于文件操作、数据库连接、网络连接、多线程与多进程同步时的锁对象管理等场合。
with语句依据冒号与缩进限定语句体范围,具体使用方式如下:
•with open(filename, mode, encoding) asfp:
#这里写通过文件对象fp读写文件内容的语句
•上下文管理语句with还支持下面的用法:
with open('test.txt', 'r') as src, open('test_new.txt', 'w') as dst:
dst.write(src.read())
文件对象属性与常用方法
readalbe( ):测试当前文件是否可读
writalbe( ):测试当前文件是否可写
seek(offset[,whence] ):
把文件指针移动到新的字节位置,offset表示相对于whence的位置。whence为0表示从文件头开始计算,1表示从当前位置开始计算,2表示从文件尾开始计算,默认为0(二进制文件)
seekalbe( ):测试当前文件是否支持随机访问
tell():返回文件指针的当前位置
truncate([size]):删除从当前指针到文件末尾的内容。如果指定了size,不论指针在什么位置都只留下前size个字符。
【例题】1. 遍历并输出文本文件的所有行内容
◼二进制文件内容操作pickle,struct,shelve
•数据库文件、图像文件、可执行文件、动态链接库文件、音频文件、视频文件、Office文档等均属于二进制文件。
•对于二进制文件,不能使用记事本或其他文本编辑软件直接进行正常读写,也不能通过Python的文件对象直接读取和理解二进制文件的内容(字节串)。
•必须正确理解二进制文件结构和序列化规则,然后设计正确的反序列化规则,才能准确地理解二进制文件内容。
•所谓序列化,简单地说就是把内存中的数据在不丢失其类型信息的情况下转成二进制形式的过程
•对象序列化后的数据经过正确的反序列化过程应该能够准确无误地恢复为原来的对象。
•Python中常用的序列化模块有pickle、struct、shelve、marshal。
使用pickle模块写入二进制文件
使用struct模块写入二进制文件
使用shelve模块操作二进制文件
▪Python标准库shelve也提供了二进制文件操作的功能,可以像字典赋值一样来写入二进制文件,也可以像字典一样读取二进制文件。