Python程序设计复习(一)

145 阅读30分钟

第二章 运算符表、达式与内置对象

一.内置对象

python中一切都是对象

(一)常量与变量

1.常量:不需要改变也不能改变的字面值,如数字和元组。
2.变量
(1)特点:
值可以变,类型也可以变
不需要声明变量的类型就可以直接赋值
可以使用中文作变量名

//判断类型的方法
type(x)
isinstance(x,int)    //内置函数,判断x是否为int类型

(2)内存管理方式:python是基于值的内存管理模式,变量中存储的是地址,而不是具体的值。执行过程是:首先把等号右侧表达式的值计算出来,然后在内存中寻找一个位置把值存储进去,最后创建变量指向这个内存地址。
(3)强类型编程
自动识别赋值运算符右侧表达式变量的类型。

x=1
y=5.3
print(x+y) #6.3

变量被创建后除非显式的进行修改删除,否则将一直保持之前的类型。
(4)变量名的命名规则
变量名必须以字母下划线开头
变量名中不能有空格或标点符号。
不能使用特殊关键字作为变量名,如内置函数。
不建议使用系统内置模块名。
变量名区分大小写。

(二)数字

1.内置的整数、实数与复数
(1)内存限制:python支持任大的数,具体上限受内存大小限制。
(2)判断相等的依据:两数之差的绝对值是否足够小,尽量避免直接比较两个实数是否相等

abs(0.4-0.3-0.1)<1e-6    #True 1e-6 :1乘以10的负6次方

因为精度问题实数相减会出现误差,但实数相加不会出现误差。

x=0.4
y=0.1
print(x-y)   #0.3000000...4
print(x+y)   #0.5

(3)复数:与数学运算完全一致。
(4)表达式求值会进行隐式的类型转换。
(5)下划线:在数字中间使用单个下划线作为分隔来提高数字的可读性。

1_2_3_4    #1234

2.分数
3.高精度计算

(三)字符串与字节串

1.特点
(1)python只有字符串类型,没有字符类型。
(2)统计字符串长度时,中文和英文字母都作为一个字符对待,也可以使用中文作为变量名。

2.字符串对象的创建和连接
(1)创建:用单引号和双引号声明字符串,单引号双引号可以相互嵌套。

x='liuzun'
y="zhangjiayou"

(2)连接
+可以实现常量与变量之间的连接

x='liuzun' 
y=" love "
str1=x+y+'zhangjiayou'+' forever'
print(str1)    #liuzun love zhangjiayou forever

空格只能用于常量与常量之间的连接

str2='liuzun' ' zhangjiayou'
print(str2)    #liuzun zhangjiayou

(3)字符串str与字节串bytes之间的转换

二.运算符与表达式---运算符连接表达式

运算符优先级(由高到低):算数运算符→位运算符→成员测试运算符→关系运算符→逻辑运算符

(一)算数运算符

1.+运算符
连接列表、元组、字符串,不能连接集合和字典(集合和字典不可变),且列表元组字符串之间不能连接

x = [1,2,3]
y = [4,5,6]
a = (1,2,3)
b = (4,5,6)
m = {1,2,3}
n = {4,5,6}
print(x+y)    #[1, 2, 3, 4, 5, 6]
print(a+b)    #(1, 2, 3, 4, 5, 6)
print(m+n)    #报错:unsupported operand type(s) for +: 'set' and 'set'
print(y+a)    #报错:can only concatenate list (not "tuple") to list

不能连接字符串与数字

'A'+1    #can only concatenate str (not "int") to str

把True和False当0和1处理

2.*运算符:支持可变序列列表、元组、字符串,不支持集合、字典(因为集合和字典不可变且不可重复),表示序列的重复

x=[1,2,3]
y=x*3
print(y)    #[1, 2, 3, 1, 2, 3, 1, 2, 3]

3./运算符、//运算符
/表示数学意义上的除法

x=3/2
y=-15/4
print(x)    #1.5
print(y)    #-3.75

//表示向下取整除法

a=3//2
b=-15//4
print(a)    #1(1.5)
print(b)    #-4(-3,75)

4.%运算符
整数或实数的求余运算,对实数求余注意精度问题

x=12%5
y=3.2%3
z=3.2%3.1
print(x)    #2
print(y)    #0.20000000000000018
print(z)    #0.10000000000000009 

用于字符串格式化,但并不推荐

(二)关系运算符> < ==

1.特点
python关系运算符可以连用,1<3<5等价于1<3and3<5
操作数之间必须可比较

'Hello'>3    #报错:'>' not supported between instances of 'str' and 'int'

具有惰性求值和逻辑短路的特点

2.> < ==的使用
比较大小

'Hello'>'world' #False
'Hello'=='world'#False
'Hello'<'world' #True
[1,2,3]<[1,2,4] #True

成员测试

[1,2,3]<[1,2,3,4] #True,既可以表示列表1小于列表2,也可以表示列表1包含于列表2
[1,2,3]<[1,2,3]   #False,两列表相等时不能用于成员测试
print('Hell'<'Hello') #True

(三)成员测试运算符in

判断一个对象是否是另一个对象的元素

print(1 in[1,2,3])    #True
print('H' in 'Hello') #True
print('h' in 'Hello') #False
for i in (3,5,7):
    print(i,end=' ')  #3 5 7

(四)同一性运算符is

判断两个对象是否相等

x=[300,200,300]
x[0] is x[1]    #False     
x[0] is x[2]    #True
x=[1,2,3]
y=[1,2,3]
z=[1,2,3,4,5]
print(x is y)    #True
print(x is z)    #False

(五)位运算符与集合运算符

(六)逻辑运算符and or not

逻辑运算符作为连接表达式的条件,具有惰性求值的特点。
1.and

x=3 > 5 and a>3
print(x)    #False

2.or

x=3 > 2 or a>3 #只要其中一个True就为True,不考虑其他表达式的对错
print(x) #True

x=3 < 2 or 5>3
print(x) #True

x=3 < 2 or a>3 #一个False一个编译错误
print(x) #Error:name 'a' is not defined

3.not

x=3 not in [1,2,3]
print(x)    #False
not 1    #False
not 3    #False
not 0    #True

4.and和or不一定返回True或False,而是得到最后一个被计算的表达式的值

print(3 or 5)    #3:第一个为True则结束语句,第一个为False则计算第二个,所以计算完3之后结束or语句
print(3>5 or 7)  #7
print(3<5 or 7)  #True

print(3 and 5)   #5:and语句两边都要运算,所以计算完5之后结束and语句 
print(3>5 and 7) #False
print(7 and 3<5) #True
print(3<5 and 7) #7

(七)矩阵乘法运算符

(八)赋值运算符

python不支持先赋值再自增运算i++,i--
支持++i,--i

i++    #SyntaxError: invalid syntax
i--    #SyntaxError: invalid syntax

负负得正原则

x=-5
print(x)    #-5
i=--5
print(i)    #5
n=------(3+5)    
print(n)         #8
n=-------(3+5)   
print(n)         #-8

三.Python常用内置函数用法精要

(一)类型转换

bin():将整数转换为二进制数
oct():将整数转换为八进制数
hex():将整数转换为十六进制数

x = int(float(input("请输入一个自然数:"))) #输入555.0
print("十进制:",x)      #555
print("二进制",bin(x))  #0b1000101011
print("八进制",oct(x))  #0o1053
print("十六进制",hex(x))#0x22b

int():将整数、实数、分数(小数)、合法数字及字符串转换为整数

//将整数、实数、分数转换为整数,int()参数列表中只有一个参数
x=3.2
print(int(x))    #3
x=-3.2
print(int(x))    #-3
//将字符串转换为整数时:int('字符串',base),将字符串按base进制转换为十进制
//base的值为0或2-36的整数,0表示按字符串隐含进制进行转换
x=555
y=bin(x)     
z=int(y,2)  #把2进制数转化为十进制整数
m=int(y,0)  #y的隐藏进制为2进制
print(y)    #0b1000101011
print(z)    #555
print(m)    #555

float():将整数、数字字符串、分数(小数)、合法数字及字符串转换为实数

complex():生成复数

x=complex(3,5)
y=complex('nan')  #非数字,若第一个参数为字符串则第不能有第二个参数
print(x)    #(3+5j)
print(type(x))    #<class 'complex'>
print(y)    #(nan+0j)

str():将任意类型参数转换为字符串类型

//整数转换字符串

x=1234
print(type(str(x)))    #<class 'str'>
print(str(x))
//列表转换字符串
x=[1234]
print(type(str(x)))    #<class 'str'>
print(str(x))
//元组转换字符串
x=(1234)
print(type(str(x)))    #<class 'str'>
print(str(x))
//集合转换字符串
x={1234}
print(type(str(x)))    #<class 'str'>
print(str(x))
////字符串转换字符串
x='1234'
print(type(str(x)))    #<class 'str'>
print(str(x))
////分数(小数)转换字符串
x=1.234
print(type(str(x)))    #<class 'str'>
print(str(x))

ord():返回单个字符的Unicode码

print(ord('a'))    #97
print(ord('A'))    #65
print(ord('刘'))   #21016

chr():返回Unicode码对应的字符

chr(65)    #'A'
chr(97)    #'A'
chr(21016) #'刘'

ascii():把对象转换为ASCII码表示

bytes():
生成字符串

把指定对象转换为字符串

把字节串转换为列表

x='刘遵'.encode()
print(x)         #b'\xe5\x88\x98\xe9\x81\xb5',是一个字节序列,表示一种编码方式,这里使用的是UTF-8编码。UTF-8是一种可变长度的编码方式,每个字符可以由1个到4个字节组成。
print(list(x))   #[229, 136, 152, 233, 129, 181]

list()、tuple()、dict()、set()、frozenset()把其他类型的数据转换为列表、元组、字典、可变、不可变集合
注意:转换为字典时,被转换的对象必须只能有两个元素

//frozenset
x = {1,2,3,4,5}
y=frozenset(x)
y.add(7)    #Error'frozenset' object has no attribute 'add'
//dict
x=['a','b','c','d','e']
y=enumerate(x,0)
print(dict(y))    #{0: 'a', 1: 'b', 2: 'c', 3: 'd', 4: 'e'}

type()、isinstance()
type():
查看参数类型

type(3)    #<class 'int'>

判断是否是某数据类型的实例(可能不可行)

type({3}) in (list,tuple,dict)    #False

ininstance( 对象的实例,数据类型 ):
判断对象的实例是不是某种数据类型

在Python中,isinstance(object, classinfo) 是一个内置函数,用于检查一个对象是否是一个特定的类或者类族的一部分。

在你的例子 isinstance(3, float or int) 中,float or int实际上是先进行一个逻辑判断。Python会先判断float是否为真,如果为真,那么就判断3是否是浮点数类型,否则(即float为假时)就判断3是否是整数类型。

但实际上,你应该分别使用 isinstance(3, float) 和 isinstance(3, int) 来检查3是否分别是浮点数或整数。这样的语法会更清晰,更符合Python的编程习惯。

 #判断3是不是int类型
x=isinstance(3, int)   
print(x)    #True
//
y=isinstance(3, float or int)    //
print(y)    #False
y=isinstance(3, int or float)
print(y)    #True
//判断数据是否是这三个数据类型之一
z=isinstance(3j,int,float,complex)
print(z)    #True

(二)最值求和

max():

计算列表元组或包其它含有限个元素的可迭代对象中所有元素的最大值,支持default参数和key参数

//生成10个1-99之内的数
from random import randint
x=[randint(1,100) for i in range(10)]
print(max(x))

key参数:指定寻找的标准,可以用lambda表达式对标准进行定义

y=['1','111',"111"]
print(max(y,key=len))    #按字符串长度找最大值

default参数:指定可迭代对象为空时的返回值

z=[]
print(max(z,key=len,default='NULL'))

min():

计算列表元组或包其它含有限个元素的可迭代对象中所有元素的最小值,支持default参数和key参数

//生成10个1-99之内的数
from random import randint
x=[randint(1,100) for i in range(10)]
print(min(x))

key参数:指定寻找的标准,可以用lambda表达式对标准进行定义

y=['1','111',"111"]
print(min(y,key=len))    #找字符串长度最小的元素

default参数:指定可迭代对象为空时的返回值

z=[]
print(min(z,key=len,default='NULL'))

sum():

计算列表元组或包其它含有限个元素的可迭代对象中所有元素的和

from random import randint
x=[randint(1,100) for i in range(10)]
print(sum(x))   

(三)基本输入输出

input():输入函数
print():输出函数

//enumerate对象的使用
for i in enumerate(range(10),7):
    print(i,end=" ")    #(7, 0) (8, 1) (9, 2) (10, 3) (11, 4) (12, 5) (13, 6) (14, 7) (15, 8) (16, 9) 
print('\n')
for j in enumerate(range(10),7):
    print(j,end='')     #(7, 0)(8, 1)(9, 2)(10, 3)(11, 4)(12, 5)(13, 6)(14, 7)(15, 8)(16, 9)

(四)排序与逆序

sorted():

可迭代对象按默认升序或其它顺序排序,返回一个新的列表

按默认升序排序

from random import randint
x=[randint(1,100) for i in range(10)]
print(x)    #例子:[88, 39, 55, 80, 63, 91, 89, 66, 83, 39]
y=sorted(x) #例子:[39, 39, 55, 63, 66, 80, 83, 88, 89, 91]
print(y)

按降序排序

from random import randint
x=[randint(1,100) for i in range(10)]
print(x)    #例子:[58, 80, 27, 54, 63, 42, 65, 28, 11, 58]
y=sorted(x,reverse=True) 
print(y)    ##例子:[80, 65, 63, 58, 58, 54, 42, 28, 27, 11]

按字符串长度排序顺序排序

from random import randint
x=[randint(1,100) for i in range(10)]
print(x)    #例子:[92, 49, 41, 68, 86, 34, 76, 29, 5, 86]
y=sorted(x,key=str)
print(y)    #例子:[29, 34, 41, 49, 5, 68, 76, 86, 86, 92]

用lambda表达式定义标准进行排序

//按字符串长度进行排序
x=['a','bb','c','dd','ee','fff','g','hhh']
print(x)
y=sorted(x,key=lambda y:len(y))    #y来自于x,按字符串y的长度排序,长度相等的相对位置不变
print(y)

//将其他数据类型转换为字符串后,按字符串长度排序
from random import randint
x=[randint(1,100) for i in range(10)]
print(x)
y=sorted(x,key=lambda y:len(str(y)))
print(y)
z=sorted(x,key=lambda y:len(str(y)),reverse=True)    #按字符串长度逆序排列
print(z)

(五)枚举 enumerate()

枚举返回的是元组

enumerate(可迭代对象,索引的初始值(默认值为0)):

将可迭代对象的元素取出并标上序号,返回新的可迭代的enumerate对象

from random import randint
x=[randint(1,100) for i in range(10)]
y=list(enumerate(x))
z=list(enumerate(range(10),3))    #给数字0-93开始编号
print(y)
print(z)

(六)map(),reduce(),filter()

map、filter返回的是新的可迭代对象,reduce返回的不是可迭代对象

map(映射关系,可迭代对象1,可迭代对象2,...)

map() must have at least two arguments.:map至少含有两个参数

将x按某种函数关系映射到y

//y=x映射
x=[1,3,5,7,9]
y=map(lambda x:x,x)
print(x)
print(list(y))
//y=2x映射
x=[1,3,5,7,9]
y=map(lambda x:x*2,x)
print(x)
print(list(y))
//z=x+y映射
x=[1,3,5,7,9]
y=[2,4,6,8,10]
z=map(lambda item1,item2:item1+item2,x,y)    //item1,item2是形参,用于接收可迭代对象x,y内的值
print(x)
print(y)
print(list(z))
//y=(x!=5),返回值是布尔值
x=[1,3,5,7,9]
y=map(lambda x:x!=5,x)
print(x)
print(list(y))

reduce(运算关系,可迭代对象)

需要函数库导入:from functools import reduce
运算关系可以导入operator库,也可以自己定义 对可迭代对象元素进行运算

from functools import reduce
#求和运算
import operator
x=reduce(operator.add,range(10))    #operator
print(x)    #45
x=reduce(lambda x,y:x+y,range(10))  #lambda函数,map函数中的x,y不可以来自同一个可迭代对象
y=reduce(lambda x,y:x*y,range(1,10))
print(x)    #45,只计算了x相加
print(y)    #362880,只计算了x相乘,map函数中的x,y不可以来自同一个可迭代对象,x来自range(10),则y不能来自range(10),那么y就没有被定义

filter(过滤条件,可迭代对象)

将可迭代对象中不符合过滤条件的元素删除,符合条件的留下

x=filter(lambda x:x%2==0,range(10))
print(list(x))    #[0, 2, 4, 6, 8]

(七)range函数

(八)zip()

zip(可迭代对象1,可迭代对象2,可迭代对象3.....)

多个可迭代对象对应位置上的元素压缩至一个元组,返回一个新的zip对象。

x=['a','b','c','d','e']
y={1,2,3,4,5,6}
z=('first','second','third','fourth','fifth')
result=zip(x,y,z)
print(result)       #<zip object at 0x00000170C0B1FE40>
print(list(result)) #[('a', 1, 'first'), ('b', 2, 'second'), ('c', 3, 'third'), ('d', 4, 'fourth'), ('e', 5, 'fifth')]

第三章 详解python序列结构

  • python序列可分为:有序序列和无序序列 ; 可变序列和不可变序列
  • 有序序列(ordered sequence)是指元素之间具有顺序关系的序列。这意味着在序列中,每个元素都有一个特定的位置,并且序列中的元素按照它们在序列中的顺序进行排列。
  • 有序是指元素之间的位置关系而不是数值关系。
y=[1,3,2,5,'无序序列',4,'有序序列']
for i in y:
    print(i,end=' ')    #1 3 2 5 无序序列 4 有序序列 
  • 在Python中,列表、元组、range对象都是有序序列,而集合、字典则不是。但是尽管集合是无序的,但集合中的元素仍然按照它们被添加到集合中的顺序进行排列。
  • 有序序列支持双向索引,即可用正数、负数表示索引。0为正向索引的第一个下标,-1为负向索引的第一下标。
y=[1,2,3,4,5]    #定义一个列表
print(y[0])      #1      
print(y[-1])     #5   
print(y[-2])     #4

一.列表:打了激素的数组

(一)列表的特点

1.存储结构:包含若干个元素的有序连续内存空间
2.存储内容:同一列表内数据的类型可以各不相同,可以同时含基本类型元素以及其他任意类型的对象

x=['2003',10,'13 男',['2003',10,'02 女'],('济','宁'),3.5,'年',{'学校 :qlu'},{'学校':'art'}]
for i in x:
    print(i,end=" ")    #2003 10 13 男 ['2003', 10, '02 女'] ('济', '宁') 3.5 年 {'学校 :qlu'} {'学校': 'art'} 

3.基于值的的自动内存管理模式:列表中存储的是值的引用,引用都是类型相同的数值,所以列表中各元素可以是不同类型的数据。
4.列表的增删:当列表增删时,列表对象自动进行扩展(元素后移)和收缩(元素前移),但效率不高,尽量在列表尾部进行增删操作。
5.缺点:列表虽功能强大,但负担比较重,开销较大。

(二)列表的基本操作

1.列表的创建

用=直接进行创建

x=[1,2,3]

list方法转化创建

x=(1,2,3)
y=list(x)
print(x)    #(1,2,3)
print(y)    #[1,2,3]
#字典转化为列表
x={'a' : 1,'b' : 2,'c' : 3}
y=list(x)
z=list(x.items())
print(y)    #['a', 'b', 'c']
print(z)    #[('a', 1), ('b', 2), ('c', 3)]

2.列表的删除

del 命令:删除后不仅是清空数据,也释放了地址。

x=[1,3,2,7,4,5,11,9]
print(x)    #[1, 3, 2, 7, 4, 5, 11, 9]
del(x)    
print(x)    #NameError: name 'x' is not defined

3.列表元素的访问

用下标进行访问

y=[1,2,3,4,5]    #定义一个列表
print(y[0])      #1      
print(y[-1])     #5   
print(y[-2])     #4

用循环进行访问

x=[1,3,2,7,4,5,11,9]
for i in x:
    print(i,end=' ')    #1 3 2 7 4 5 11 9 

4.列表的常用方法

元素增加

都属于原地操作,不返回新的列表

append(value):在列表尾部追加一个元素value

x=[1,2,3,4,5,6]
x.append(7)
print(x)    #[1, 2, 3, 4, 5, 6, 7]

insert(index,value):在index处插入一个元素value

x=[1,2,3,4,5,7]
x.insert(5, 6)    #在索引5处加一个6
print(x)    #[1, 2, 3, 4, 5, 6, 7]

extend()在列表尾部追加一个可迭代对象中的所有元素

x=[1,2,3,4,5,7]
y={'a','b','c'}
z={'d' : 1,'e' : 2,'f' : 3}
s=(8,9,10)
print(x)
x.extend(y)
print(x)
x.extend(z)
print(x)
x.extend(s)    #只能追加键值
print(x)
x.extend(range(11,14))
print(x)
元素删除

都属于原地操作,不返回新的列表

pop(index):删除并返回index位置上的元素

x=[1,2,3,4,5,7]
y=x.pop(5)
print('弹出的元素是:',y)    #弹出的元素是: 7
print(x)    #[1, 2, 3, 4, 5]

remove(value):删除第一个与value相同的元素

x=[1,2,3,4,5,7,7]
y=x.remove(7)
print(x)    #[1, 2, 3, 4, 5, 7]

clear():清空列表中所有元素

x=[1,2,3,4,5,7,7]
x.clear()
print(x)    #[]
查找

count(value):返回value出现的次数

x=[1,2,3,4,5,7,7]
y=x.count(7)
print('7出现的次数是:',y)    #7出现的次数是: 2

index(value):返回value首次出现的索引

x=[1,2,3,4,5,7,7]
y=x.index(7)
print('7出现的位置是:',y)    #7出现的位置是: 5
排序与逆序

原地操作,不返回新的列表
sort()方法与reverse()方法:与sorted、reversed内置函数类似,只是在原列表内操作,不返回新的列表

import random
x=list(range(11))
print('原列表的顺序是:',x)    #原列表的顺序是: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
random.shuffle(x)            #属于原地操作
print('打乱后列表的顺序是:',x)#打乱后列表的顺序是: [2, 9, 0, 6, 7, 1, 4, 10, 3, 5, 8]
x.sort() 
print('排序后列表的顺序是:',x) #排序后列表的顺序是 [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
x.reverse()
print('逆序后后列表的顺序是:',x) #逆序后后列表的顺序是: [10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

sort方法与sorted函数区别体现

import random
#sorted函数
x1=list(range(11))
random.shuffle(x1)
y1=sorted(x1)
print(x1)    #保留了原来的列表数据
print(y1)    #y1得到了返回值,是排序后新的列表
#sort方法
x2=list(range(11))
random.shuffle(x2)
y2=x2.sort()
print(x2)    #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
print(y2)    #None,y2不得到返回值
复制

都不属于原地操作
引用:列表中元素的首地址
copy():
copy是浅复制:把列表中所有元素的引用复制新列表中,不属于原地操作
特点:非空、非单元素子列表元素改变相互影响,单字符改变不相互影响

x=[1,2,3,[4,5]]
y=x.copy()
x[3].append(6)    #y改变
x[0]=7            #y不改变
x.append(8)       #y不改变
print(x)          #[7, 2, 3, [4, 5, 6], 8]
print(y)          #[1, 2, 3, [4, 5, 6]]

单元素列表和空列表的赋值修改的影响

x=[1,2,3,[4,5],[6]]
print('x列表的初始值:',x)       #x列表的初始值: [1, 2, 3, [4, 5], [6]]
y=x.copy() 
y[4]=[7]                        #首值变,引用已经修改
y[4].append('不相互影响')       #y[4]的引用已经发生修改,对y子列表进行操作不影响x
y[3].append('相互影响')
print('y列表改变后的x列表:',x) #y列表改变后的x列表: [1, 2, 3, [4, 5, '相互影响'], [6]]
print('y列表改变后:',y)        #y列表改变后: [1, 2, 3, [4, 5, '相互影响'], [7, '不相互影响']]
x=[1,2,3,[4,5],[6],[]]
print('x列表的初始值:',x)
y=x.copy()
y[3]=[]                #首值变,引用已经修改
y[4].append('不相互影响') #y[4]的引用已经发生修改,对y子列表进行操作不影响x
y[3].append('相互影响')
print('y列表改变后的x列表:',x) 
print('y列表改变后:',y)

copy.deepcopy(list):
需要导入函数copy: import copy
copy.deepcopy()函数是深复制:对列表中所有元素进行递归,把所有值复制到新列表中,新列表与原列表相互独立互不影响。
copy.deepcopy()函数的结果是两份不同的引用指向两个元素相同列表。

import copy
x=[1,2,3,[4,5]]
y=copy.deepcopy(x)
x[3].append(6)    
x[0]=7            
x.append(8)
y.append(10)       
print(x)          #[7, 2, 3, [4, 5, 6], 8]
print(y)          #[1, 2, 3, [4, 5], 10]

将一个相同的列表赋值给两个变量
这两变量相互独立互补影响

用=赋值
把一个列表变量x赋值给列表变量y,则x与y存储的引用相同指向同一个列表,对其中一个做任意修改都会使另一个列表做相应的修改。
与copy()方法相同都是对引用进行操作,但是copy()方法的结果是两份相同的引用x,y指向同一组列表变量,而=赋值后的结果是x与y共用同一份引用指向同一组列表变量。所以copy方法只有在对子列表操作时才相互影响,而对单元素进行操作时互不影响。

x=[1,2,3,[4,5]]
y=x
x[3].append(6)    
x[0]=7            
x.append(8)
y.append(10)       
print(x)          #[7, 2, 3, [4, 5, 6], 8, 10]
print(y)          #[7, 2, 3, [4, 5, 6], 8, 10]

4.列表对象支持的运算符

追加元素

+:实现列表元素的增加,涉及大量元素复制,效率非常低,不属于原地操作。

x=[1,2,[3,4,5]]
x+[6]
print(x)      #[1, 2, [3, 4, 5]],列表元素未发生改变,不属于原地操作
print(id(x))  #原地址2303579337664

x=x+[6]
print(x)      #[1, 2, [3, 4, 5], 6]
print(id(x))  #地址发生化2303579340224

x=x+[[7,8,9]]
print(x)      #[1, 2, [3, 4, 5], 6, [7, 8, 9]],可一次增加大量元素
print(id(x))  #地址发生化2303579340608

+=:实现列表的追加,与extend方法一样高效,属于原地操作

x=[1,2,[3,4,5]]
print(id(x))    #2303578433600
x+=[6]
print(x)        #原地操作,[1, 2, [3, 4, 5], 6]
print(id(x))    #2303578433600
元素重复运算符

:列表与整数相表示列表的重复,返回新的列表,不属于原地操作

*=:也表示列表重复,但属于原地操作

成员测试符 in

用于查询列表中是否包含某个元素,查询时间随着列表长度的增加而线性增加,同样的操作对集合而言则是常数级的。

内置函数

max()
min()
sum()
len():返回列表中元素个数
zip()
enumerate()
map()
filer()
all():测试列表中所有元素是否等价于True
在Python中,以下是一些被视为等价于 True 的值:

  1. 非空字符串(例如:"hello")
  2. 非零数字(例如:1,2,3,-1,-2,-3等)
  3. 非空集合(例如:{1, 2, 3}, {'a', 'b', 'c'}等)
  4. 非空列表(例如:[1, 2, 3],[1, 'a', 3.14]等)
  5. 非空元组(例如:(1, 'a'), ('hello', 'world')等)
  6. 非空字典(例如:{'name': 'Alice', 'age': 25}等)
  7. 非空枚举(在Python 3.7以后的版本中引入)
  8. 非空生成器(通过调用一个生成器函数或使用内置的 iter() 函数得到的生成器对象)
  9. 非空的上下文管理器(通过使用 with 关键字和 __enter__() 和 __exit__() 方法定义的上下文管理器)
  10. 非空的类型(例如:None,整数,浮点数,字符串,布尔值,集合,列表,元组,字典,生成器,上下文管理器等)
x=[1,2,[3,4,5],'liu',(7,8,9),{'zun'},{'a' : 'you'}]
print(all(x))    #True
y=[1,2,[3,4,5],'liu',(7,8,9),{'zun'},{'a' : 'you'},[],{},()]
print(all(y))    #False

any(): 测试列表中是否有元素等价于True
以下是被视为等价于 False 的值:

  1. 空字符串(例如:"")
  2. 零或负零
  3. 空集合(例如:set(),{}等)
  4. 空列表(例如:[]等)
  5. 空元组(例如:()等)
  6. 空字典(例如:{}等)
  7. None
  8. 布尔值 False
  9. 空生成器(通过调用一个生成器函数或使用内置的 iter() 函数得到的生成器对象,如果它不产生任何元素)
  10. 空的上下文管理器(通过使用 with 关键字和 __enter__() 和 __exit__() 方法定义的上下文管理器,如果它不执行任何操作)
y=[1,2,[3,4,5],'liu',(7,8,9),{'zun'},{'a' : 'you'},[],{},()]
print(any(y))    #True

(三)列表推导式

1.概念

列表推导式也称列表解析式,可以使用非常简洁的方式对列表或其他可迭代对象进行遍历过滤再次计算

2.形式

[ 表达式 for 表达式中的元素 in 可迭代对象 if condition过滤条件 ]
形式可以分为三部分,每部分之间的分隔符是空格

  • 表达式---表达式的结果是列表中的元素
  • for至可迭代对象---相当于变量取值的声明
  • if条件---过滤条件

3.应用

实现嵌套列表的平铺

降低列表的深度

vec=[[1,2,3],[3,4,5],[6,7,8]]
x=[num for i in vec for num in i]     #i取自vec,num取自i
print(x)    #[1, 2, 3, 3, 4, 5, 6, 7, 8]     

若有多级嵌套或者多级子列表嵌套深度不同,则需要使用函数递归实现

过滤不符合条件的元素

使用if condition 过滤

过滤数字
from random import randint
x=[randint(1,100) for i in range(10)]
print('过滤前的列表:',x)    #过滤前的列表: [98, 11, 10, 98, 90, 73, 97, 74, 17, 88]
y=[i for i in x if i>=50]
print('过滤后的列表',y)      #过滤后的列表 [98, 98, 90, 73, 97, 74, 88]
过滤最高成绩
scores={'刘遵' : 97.2,'张嘉佑' : 99.3,'张敏': 100}
y=max(scores.values())
print(y)
x=[name for name ,score in scores.items() if score==y]
print(x)
寻找列表中最大元素的位置
from random import randint
x=[randint(1,10) for i in range(20)]
print(x)                        #[3, 3, 10, 3, 7, 9, 8, 10, 8, 7, 1, 6, 6, 10, 8, 7, 2, 10, 10, 7]
maxSum=max(x)
y=[index for index,num in enumerate(x) if num==maxSum]    #index与num的顺序不能改变,与enumrate函数的默认参数顺序相同
print('最大元素的位置是:',y)    #最大元素的位置是: [2, 7, 13, 17, 18]
同时遍历多个列表或可迭代对象

两个for语句之间的分隔符为空格

result1=[x*y for x in[1,2,3] for y in {4,5,6}]
result2=[(x,y) for x in[1,2,3] for y in {4,5,6}]
print(result1)    #[4, 5, 6, 8, 10, 12, 12, 15, 18]
print(result2)    #[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]

if条件只限制其前面,最近的一个for语句

res=[(x,y) for x in[1,2,3] if x==1 for y in {4,5,6} if y!=x]
print(res)
矩阵转置
表达式可以为函数或复杂表达式
[f(v) for v in [1,2,-1,4] if v>0]
支持文件对象迭代
生成100以内的所有素数
[p for p in range(2,100) if 0 not in
[p%d for d in range(2,int(sqirt(p)+1)]]

(四)切片

切片的操作都是列表间的操作

1.形式

[start:end:step]
start:起始位置,为0时可省略
end:结束位置(不包括),为列表长度时可省略
step:步长,为1时可省略
第一个::不可省略
第二个::step为1时,可省略

2.特点

(1)当step为负数时,表示反向切片,但要注意start指向的元素要在·Q1stop指向元素的右侧

aList=[1,2,3,4,5]
y=aList[4:1:-1]
z=y=aList[-1:1:-1]    #-14都指向第5个元素
print(y)    #[5, 4, 3]
print(z)    #[5, 4, 3]

(2)切片操作不会因为下标越界而抛出异常,而是在列表尾部和头部进行截断。

aList=[1,2,3,4,5]
x=aList[:100]
print(x)     #[1, 2, 3, 4, 5]

3.切片操作

(1)获取列表元素

不属于原地操作,返回有一个新的列表

(2)为列表增加元素

属于原地操作
在头部增加,stop为0

aList=[1,2,3,4,5]
aList[:0]=[-3,-2,-1,0]
print(aList)    #[-3, -2, -1, 0, 1, 2, 3, 4, 5]

在尾部增加,start为列表长度

aList=[1,2,3,4,5]
aList[len(aList):]=[6,7,8,9]
print(aList)    #[1, 2, 3, 4, 5, 6, 7, 8, 9]

在中间插入,一次只能插入一个,start=stop=等于插入位置

aList=[1,2,3,4,6]
aList[4:4]=[5]
print(aList)    #[1, 2, 3, 4, 5, 6]
(3)替换,修改列表中的元素

属于原操作
操作前要看切片是否连续:step为1或-1时切片连续,其他切片不连续

切片不连续时
替换位置的个数要与提供的元素个数相等

//要替换的位置为0,2,4三个位置,但提供了四个元素
x=[1,3,5,7,9]
x[::2]=[2,4,6,7]
print(x)    #ValueError: attempt to assign sequence of size 4 to extended slice of size 3
//要替换的位置为0,2,4三个位置,提供了三个元素
x=[1,3,5,7,9]
x[::2]=[2,4,6]
print(x)    #[2, 3, 4, 7, 6]
//要替换的位置为0,2,4三个位置,提供了两个元素
x=[1,3,5,7,9]
x[::2]=[2,4]
print(x)    #ValueError: attempt to assign sequence of size 2 to extended slice of size 3

切片连续时
替换位置的个数要与提供的元素个数不需要相等

//替换位置个数大于提供元素个数,替换位置上的元素被覆盖,多出的替换位置元素消失
aList=[1,2,3,4,5]
aList[1:4]=[21,27]
print(aList)    #[1, 21, 27, 5]
//替换位置个数等于提供元素个数
aList=[1,2,3,4,5]
aList[1:3]=[21,27]
print(aList)    #[1, 21, 27, 4, 5]
//替换位置个数小于提供元素个数,只有替换位置上的元素被覆盖,多出的提供元素仍然进入列表
aList=[1,2,3,4,5]
aList[1:3]=[21,27,35,47]
print(aList)    #[1, 21, 27, 35, 47, 4, 5]
(4)map、zip、filter函数的应用
map(映射关系,可迭代对象)
aList=['a',1,'b',2,'c',0]
aList[1::2]=map(lambda x:x!=0,range(3))    #x来自于可迭代对象range(0)
print(aList)    #['a', False, 'b', True, 'c', True]
zip(iter1,iter2,...itern)
aList = ['a', 1, 'b', 2, 'c', 0]  
new_elements = list(zip(('刘遵','张嘉佑','张敏'),('男','女','女'),['20','20','45']))  # 将zip对象转换为列表  
aList[1::2] = new_elements  # 将新的元素列表插入到原列表的指定位置  
print(aList)

为什么不行?

aList = ['a', 1, 'b', 2, 'c', 0]
x=('刘遵','张嘉佑','张敏')
y={20,20,45}     #2023 12 28 因为集合不能重复
z=['男','女','女']
new_elements = list(zip(x,y,z))  # 将zip对象转换为列表  
aList[1::2] = new_elements  # 将新的元素列表插入到原列表的指定位置  
print(aList)

filter(过滤条件,iter)

(5)使用切片删除列表中的元素

=[]删除

aList=[3,5,7,9,11]
aList[0:3]=[]
print(aList)     #[9, 11]

del关键字删除

aList=[3,5,7,9,11]
del aList[0:3]
print(aList)    ##[9, 11]