1,列表 list
(1)列表是由一系列特定元素组成的,元素和元素之间没有任何关联关系,但他们之间有先后顺序关系
列表是一种容器(用来存储数据)
列表是序列的一种
列表是可以被改变的序列
(2)创建空列表的字面值
L = [ ] #L绑定空列表
创建非空列表:
L = [1 , 2 , 3 , 4]
L = ['北京','上海', '重庆']
L = [1,‘two’,3,‘四’]
L = [1, 2, [3.1 ,3.2 ,3.3],3.4]
列表的构造(创建)函数list
list() 生成一个空的列表 等同于[]
list(iterable) 用可迭代对象创建一个列表
实例:
L = list() L为空列表
L = list("ABCD") L->['A','B','C','D']
L = list(range(1,10,2)) L->[1,3,5,7,9]
(3)列表的运算:
算数运算 + += * *=
+用于拼接列表(作用于可迭代对象)
[1,2,3] + [4,5,6] = [1,2,3,4,5,6]
[1,2,3] + ‘king’ = [1,2,3,‘k’,‘i’,‘n’,‘g’]
*只能作用于整数,用于生成重复的列表
[1,2,3]*3 ->[1,2,3,1,2,3,1,2,3]
列表的比较运算: < <= > >= == !=
x = [2] y = [1,2,3,4,5] ->x>y(比较方法与字符串类似,按位比较)
[‘AB’,‘CD’]<[‘AC’,‘BD’]->每个对象按位比较
[1,‘two’] 与[‘two’,1] TypeError仅限列表内为同种类型的两个列表才能比较
[1,2,1]>[1,2] ->前面相同时,长者大
所有容器的共有运算符:in / not in
判断一个对象是否在一个容器内
可变对象与不可变对象的区别:
list列表为可变对象:
tmp = [1,2,3]
a = id(tmp)
tmp+=[4,5,6]
b = id(tmp)
这里a == b,可变对象的扩展赋值,内存地址不变
如果tmp为字符串a != b不可变对象扩展赋值,内存地址改变,因为a+b赋值到一个新地址
此外,若x,y均为list对象,y = x赋值过后,相当于一个内存单元的链接数加1,实际为一个对象,类似于C++的引用。故x与y的内存地址一样,修改x,y也同样被修改。
(4)列表的切片[ : : ]
等同于字符串的切片规则,注意与range对比:range()为小括号,不同参数之间用逗号‘,’隔开,列表为‘:’
L = list(range(9))
L[0:9:2] - >[0,2,4,6,8]
切片赋值语法:(切片赋值等号右边必须为可迭代对象,而索引赋值可以为对象)
列表[切片] = 可迭代对象
L = [2,3,4]
L[0:1] = [1.1,2.2]->[1.1,2.2,3,4]
注意这里不是[[1.1 , 2.2] , 3 ,4]
L[1:1] = [4,5]->[2,4,5,3,4]此时不是替换,而是插入
L[3:3] = [5,6] ->[2,3,4,5,6]此时在末尾插入
L[1:2] = [] ->[2,4]此时将下标为1的对象删除
L = [1,2,3,4,5,6,7,8]
L[1::2] = [2.2,4.4,6.6,8.8]->[1,2.2,3,4.4,5,6.6,7,8.8]
切片注意事项:
对于步长不为1的切片赋值,赋值运算符的右侧的可迭代对象提供元素的个数一定要等与切片切出的段数
del语句:用来删除列表元素
del 列表[索引]
del 列表[切片]
实例:
L = [1,2,3,4,5,6]
del L[0] #L = [2,3,4,5,6]
del L[-1] #L = [2,3,4,5]
del L[::2] #L = [3,5]
python3中常用的序列函数(可迭代对象均可使用,例如len可适用于list,max可用于str):
len(x) 返回序列的长度
max(x)返回序列的最大值元素
min(x) 返回序列的最小值元素
sum(x)返回序列中所有元素的和(元素必须时数值类型)
any(x) 真值测试,如果列表中其中一个值为真值则返回True,否则返回False
all (x) 真值测试,如果列表中所有值都为真值,则返回True,只要有一个为假,则返回False
(5)list常用方法
L.index(v[,begin[,end]]) 返回对应元素的列表索引下标(不论指定的start与end),begin为开始索引,end为结束索引,当不存在时触发ValueError错误
L.insert(index,obj) 将某个元素插放在列表中指定的位置前面
如L=[1,2,3]
L.insert(0,4)->L = [4,1,2,3]
L.count(obj) 返回列表中对象存在的个数
如L = [1,2,3,1]
L.count(0)->0
L.count(1)->2
L.remove(obj) 从列表中删除第一次出现在列表中的值
如L.remove(1)->L = [2,3,1]
如果remove一个不存在的obj会触发ValueError错误
L.copy() 复制此列表(只复制一层,不会复制深层对象)
不等同于链接,相当于重新申请内存
L.append(obj)在列表的最后追加元素
例如:L = [1,2,3]
L.append([4,5,6]) ->L = [1,2,3,[4,5,6]]
L.append(7) ->L = [1,2,3,[4,5,6],7]
L.extend(list) 相当于+=运算符
例如:L = [1,2,3]
L.extend([4,5,6]) ->L = [1,2,3,4,5,6]
L.clear() 将列表元素清空为空列表
L.sort(reverse = False)将列表中的元素进行排序,默认递增顺序
例如:L = [5,4,3,2,1]
L.sort()->L = [1,2,3,4,5]
L.sort(reverse = True) ->L = [5,4,3,2,1] 逆序排列
L.reverse() 将列表内的元素逆序
例如L = [4,5,2,1]
L.reverse() ->L = [1,2,5,4]
L.pop([index]) 默认为弹出最后一个元素,加入index等同于del语句,但del语句不会返回对象,pop可以返回弹出的对象
L.pop(2) 等同于 del L[2]
例如L = [8,7,4,3]
v = L.pop(1) -> v =7; L = [8,4,3]
(6)列表推导式(list conprehension)
列表推导式时用可迭代对象依次生成带有多个元素的列表的表达式
作用:用简易方法生成列表
语法:
[表达式 for 变量 in 可迭代对象]
或[表达式 for 变量 in 可迭代对象 if 真值表达式]
示例:
#以下生成一个数值为1~9的平方的列表
L = [x*x for x in range(1,10)]
#以下生成一个1~100内的奇数的列表
L = [i for i in range(1,101) if i%2==1]
流程:拿出可迭代对象-》绑定变量-》判断变量的真值表达式-》执行生成列表元素表达式
列表推导式的嵌套:
语法:[表达式1
for 变量1 in 可迭代对象1 if 真值表达式1
for 变量2 in 可迭代对象2 if 真值表达式2
…]
可读性较差,一般不使用嵌套
示例:
#将L1中的全部元素与L2中的全部元素依次相乘后放到列表L3中
L1 = [2,3,5]
L2 = [7,11,13]
L3 = [x*y for x in L1 for y in L2]
print(L3)
2、赋值引用、深层拷贝deep copy与浅层拷贝 shallow copy:
b = a:赋值引用,a和b都指向同一个对象,其实就是对象的引用(别名)
浅拷贝:拷贝父对象,不会拷贝对象的内部的子对象。
例如:
L = [3.1,3.2]
L1 = [1,2,L]
L2 = L1.copy() #等同于L1[:] 浅拷贝
print(L1) #[1,2,[3.1,3.2]]
print(L2) #[1,2,[3.1,3.2]]
L2[2][0] = 3.14
print(L1) #[1,2,[3.14,3.2]]
print(L2) #[1,2,[3.14,3.2]]
常数通常存在于固定的内存单元,浅拷贝仅仅创建新的变量,单变量仍然绑定于固定的常量数据的内存单元,相当于该内存单元的链接数增加
深拷贝:copy 模块的 deepcopy 方法,完全拷贝了父对象及其子对象
import copy #导入copy模块
L = [3.1,3.2]
L1 = [1,2,L]
L2 = copy.deepcopy(L1) #深拷贝
print(L1) #[1,2,[3.1,3.2]]
print(L2) #[1,2,[3.1,3.2]]
L2[2][0] = 3.14
L2[0] = 0
print(L1) #[1,2,[3.1,3.2]] #不会被改变
print(L2) #[0,2,[3.14,3.2]]
3,元组Tuple
元组是不可改变的list序列,元组可以存放任意类型的元素,一旦元组生成,则它不可以改变
表示方式:
用小括号()括起来,单个元素括起来用逗号(,)区分是单个对象还是元组
#创建空元组的字面值
t = ()
#创建非空元组的字面值
t = 100,
t = 1,2,3
t = (100,)
t = (1,2,3)
#访问元组
t = 1,2,3 #t = (1,2,3)
t[1] #t[1] = 2
元组的错误示例:
t = (200) #t 绑定整数
x,y,z = 100,200,300 #序列赋值,等号右边虽然是元组,但拆分为一个赋给左边,等同于整数赋值
x,y,z = ‘abc’
x,y,z = [10,20,30]
del t[1] #元组内元素不可以删除,只能使用del删除整个元组
元组的构造函数
tuple()生成一个空的元组,等同于()
tuple(iterable)用可迭代对象生成一个元组
示例:
t = tuple()
t = tuple(range(10))
t = tuple('hello')
t = tuple([1,2,3,4])
序列的运算符与索引切片取值和列表相同
仅有的两个方法:
T.count(value) 获取value在元组中的个数
T.index(v[,begin[,end]])获取v在元组中的索引
函数相同:len,max,min,sum,any,all
两个内置函数:
reversed(seq)反转迭代器的序列值,返回反向迭代器
也就是说在经过reversed()的作用后,返回的是一个把序列值经过反转之后的迭代器,所以,需要通过遍历,或者next()等方法,获取作用后的值
例如:
list(reversed([1,3,5,7]))
tuple(reversed((1,2,3)))
sorted(iterable,reverse = False) 将可迭代对象排序后返回一个结果列表,默认正序,reverse = True为逆序
4,字典
字典是一种可变的容器,可以存储任意类型的数据;每个数据都是用‘键’(key)进行索引,而不像序列可以用下标来进行索引;数据没有先后顺序关系,存储时无序的;数据以键(key)-值(value)的键值对进行映射存储;键不能重复,且只能用不可变类型作为字典的键(字符串,整数,元组),值没有要求
键值之间用:分隔开,键值对之间用,分隔开
#创建空字典
d = {}
#创建非空字典:
d = {'name' : 'junfu' , 'age' : 15}
d = {1:'yi' , 2:'er'}
字典的构造函数dict
dict() 创建一个空字典,等同于{}
dict(iterable) 用可迭代对象初始化一个字典
dict(**kwargs) 关键字传参形式生成一个字典,
例如 dict(name = ‘junfu’,age = 15)
dict(name = ‘junfu’,age = 15)
示例:
d = dict([('name','junfu'),('age',15)])
d = dict(name = 'junfu',age = 15)
d = dict(('ab','cd')) ->d = {'a': 'b','c': 'd'} #必须是两个元素
键索引: 字典[键]
例如
> d = {'name' : 'jfw','age' :15} d['age'] # 15
> 若不存在这个键,将返回KeyError错误
del 语句删除字典的元素: del 字典[键]
字典的in / not in
仅仅判断一个键是否存在于字典中
示例:
d = {'a' = 1,'b' = 2}
'a' in d #True
1 in d #False
字典的迭代访问,访问的是键
示例:
d = {1:'a',2:'b',3:'c'}
for i in d:
print(i) #1 2 3
print(d[i]) #'a' 'b' 'c'
内置函数:len,max,min,sum,any,all均作用于键
字典方法:
D.clear() 清空字典
D.pop(key) 移除键,同时返回此键对应的值
d = {'one':1,'two':2}
v = D.pop('one')
print(v) # 1
D.copy() 返回D的副本,只复制一层(浅拷贝)
D.update(D2) 将字典D2合并到D中,如果键相同,则此键的值取D2的值作为新值
d = {1:'壹',2:'two'}
d2 = {1:'一',3:'三'}
d.update(d2) #d = {1:'一',2:'two',3:'三'}
D.get(key,default) 返回键key所对应的值,如果没有此键,则返回default
d = {1:'壹',2:'two'}
d[3] #返回KeyError 错误
d.get(3) #默认返回None或空(什么都不返回)
d.get(3,"没有") #返回“没有“
D.keys() 返回可迭代的 dict_keys集合对象
D.values() 返回可迭代的 dict_values值对象
D.items 返回可迭代的 dict_items键值对值对象
以上将每个键值对都作为元组形式返回
d = {1:'壹',2:'two'}
d.keys() #dict_keys([1,2])
d.values() #dict_values(['壹','two'])
d.items() #dict_items( [ ( 1 , '壹' ), ( 2 , 'two' ) ] )
for k,v in d.items():
print(k,v) #k是键,v是值**
#等同于:
for k in d:
print(k,d[k])
字典推导式
字典推导式是用可迭代对象依次生成字典内元素的表达式
语法:
{键表达式:值表达式 for 变量 in 可迭代对象 if 真值表达式}
注:if 语句可省略
示例:
d = {x : x*x for x in range(10) if x%2==0}
#d = {0:0,2:4,4:16,8:64}
5,集合 set
集合是可变的、数据对象是唯一的、无序的、元素必须是不可变对象、可迭代的,相当于只有键没有值的字典。
#创建空的集合
s = set() #set()表示空的集合
#创建非空集合
s = {1,2,3}
构造函数
set() #创建空的集合
set(iterable) #用可迭代对象创建一个新的集合对象
示例:
s = set(“ABC”)
s = set(‘abccba’) #s = {‘a’,‘b’,‘c’,‘c’,‘b’,‘a’}
s = set({1:‘一’,2:‘二’,5:‘五’}) #字典转换集合只存放键 s = {1,2,5}
s = set([1 , 2 , [3.1,3.2] , 4]) #会报错,列表元素是可变对象
s = set({1:‘一’,2:‘二’}.items) #s = {(1,‘一’),(2,‘二’)}使用items会把字典的值也保存下来,每个键值对存放在一个元组中,只存放值可以使用values方法
集合的运算:
交集 & 生成两个集合共有元素的交集
并集 | 生成两个集合所有元素的并集(去掉重复的)
补集 - 生成属于s1,但不属于s2的所有元素的集合
s1 = {1,2,3,4} s2 = {2,3,5} s1-s2 ->{1,4}
对称补集 ^ 生成s1中不存在的s2的元素与s2中s1不存在的元素集合
相当于(s1-s2)|(s2-s1)
s1 = {1,2,3,4} s2 = {2,3,5} s1^s2 -> {1,4,5}
判断子集 <
判断一个集合是否一个集合的子集,返回bool值
判断超集 >
判断一个集合是否一个集合的超集,返回bool值
s1 = {1,2,3}
s2 = {1,2}
s1是s2的超集,s2是s1的子集
若类似s1 = {1,2} s2 = {3,4}
则s1与s2不互为子集关系,均返回False
判断集合是否完全相同(与集合内元素顺序无关)== !=
in / not in运算符
集合函数:max,min,len,sum,any,all
集合方法:
S.add(e) 在集合中添加一个新的元素e(不可变对象:整数,字符串,元组),如果e已经存在,则不添加
S.remove(e) 删除集合中的e元素,如果不存在e则报错:KeyError
S.discard(e) 删除集合中的e元素,如果不存在e则忽略错误
S.clear() 清空集合
S.copy() 将集合进行浅拷贝
S.pop() 从集合中删除并返回一个随机元素,如果集合为空,会出现KeyError错误
S.update(s2) 等同于S = S|s2
S.difference(s2) 等同于S-s2
S.intersection(s2) 等同于S&s2
S.intersection_update(s2) 等同于S = S&s2
S.isdisjoint(s2) 如果S与s2交集为空则返回True
… … … … … … … … …
这些方法都可以用运算符替代
集合推导式:用可迭代对象来创建(生成)集合的表达式
语法:
{表达式 for 变量 in 可迭代对象 if 真值表达式}
示例:
L = [2,3,5,7,3]
s = {x**2 for x in L } #s = {4,9, 25,49}
固定集合 frozenset
问题导向:如何让集合作为字典的键(字典的键必须是不可变对象)
作用:固定集合可以作为字典的键,也可以作为集合的值(集合的值也必须是不可变对象)
#创建空的固定集合
fs = frozenset()
#创建非空的固定集合
fs = frozenset([1,2,3,4,5])
构造函数
frozenset() 创建空集合
frozenset(iterable) #同set函数一致,返回固定集合