1.列表list

1.1 列表生成

列表是由一系列特定元素组成的,元素和元素之间没有任何关系,但他们之间有先后顺序的关系

列表是一种容器—列表是序列的一种—列表是可以被改变的序列

  • 创建空列表的字面值:
1
L = [ ]#绑定空列表
  • 创建非空列表:
1
2
L = [1,2,3,4]
L = [“北京”,”上海”,”重庆”]
  • 列表的构造:

    • list( )生成一个空的列表 等同于[ ]

    • list(iterable)用可迭代对象创建一个列表

1
2
3
a = [1,1,None,1,[1,2],'sda',4,print]
a[7]('q123')# 列表中可以包含关键字
#执行了打印语句

image-20220720163446179

1.2 列表的运算

  • 算术运算:
    • +用于拼接列表
    • +=用于原列表左侧可迭代对象进行拼接,生成新的列表
    • *用于生成重复的列表
    • *=用于生成重复的列表,同时用变量绑定新列表
    • in/not in判断一个数据元素是否存在于容器(列表)

image-20220720163836250

  • 列表的索引/切片:index/slice
    • 列表的索引语句:列表[整数表达式]
    • 用法:列表的索引取值与字符串的索引取值规则完全相同。列表的索引分为正向索引和反向索引
    • img
1
2
3
4
5
#字符串切片的应用练习
weekstr = "星期一星期二星期三星期四星期五星期六星期日"
weekid = eval(input("请输入数字1-7:"))
pos = (weekid-1) * 3
print(weekstr[pos:pos+3])

image-20220720163949298

  • 列表的索引赋值操作:
    • 列表是可变的序列,可以通过索引赋值改变列表元素
    • 语法:列表[索引] = 表达式
1
2
3
4
5
6
#实现修改字符串中某个位置的元素的方法
a = 'abcdefgh'
a = a[:2] + 'z' + a[3:]#字符串切片的方法
b = list(a)
b[2] = 'z'
a = ''.join(b)#先转化为列表,在粘在一起,join的用法

image-20220720164102436

  • 列表的切片:
    • 列表[:]
    • 列表的[::]
    • 列表的切片取值返回一个列表,规则等同于字符串的切片规则

image-20220720164723207

  • 列表切片的赋值语法:
    • 列表[切片]=可迭代对象
    • 说明:切片赋值的赋值运算的右侧必须是一个可迭代对象
1
2
3
4
5
6
7
# 说明:切片赋值的赋值运算的右侧必须是一个可迭代对象!
L = [2,3,4]
L[0:1] = [1.1,2.2] # 切片赋值
print(L)
L[1:1] = [5.5] #表示插在一号之前,必须为可迭代对象!!
L[0:0] = [8.8] #表示插在首位元素
print(L)
  • del语句:用于删除列表元素
    • 语法:del 列表[索引]或者del 列表[切片]

1.3 列表函数

常用的序列函数:

  • len(x)返回序列长度
  • max(x)返回序列中最大值元素
  • min(x)返回序列中的最小值元素
  • sum(x)返回序列中所有元素的和(元素必须是数值类型)
  • any(x)真值测试,如果列表中其中有一个值为真值,则返回True,否则返回False
  • all(x)真值测试,如果列表中所有值为真值,则返回True,只要有一个为假,则返回False

列表方法:

  • l.index(v[,begin[,end]])返回对应元素的索引下标,begin为开始索引,end为结束索引,当value不存在时触发ValueError错误
  • l.insert(index,obj)将某个元素查房到列表中指定的位置
  • l.count(x)返回列表中的元素的个数
  • l.remove(x)从列表中删除第一次出现在列表中的值
  • l.copy()复制此列表(只复制一层,不会复制深层对象)
  • l.append(x)向列表中追加单个元素
  • l.extend(list)向列表中追加一个列表
  • l.clear()清空列表,等同于l[:]=[]
  • l.sort(reverse=false)将列表中的元素进行排序,默认值按值的由小到大的顺序排
  • l.reverse()列表的反转,用来改变原列表的先后顺序
  • l.pop([index])删除索引对应的元素,如果不加索引,默认删除最后的元素,同时返回删除元素

字符串文本解析方法

1
2
3
4
s.split(sep=None)
#将字符串,使用sep作用为分隔符分隔S字符串,返回分割后的字符串的列表,当不给定参数时,用空白字符作为分隔符进行分隔
s.join(iterable)
#用可迭代对象中的字符串,返回一个中间用s分隔的字符串
1
2
print('1 2 3 4 5 6 7\n8\t9'.split(' '))
print(' '.join(['1','2','3',' ','4','5','6','7\t8\n9']))

image-20220720165552896

1.4 深浅拷贝

深拷贝(deep copy)和浅拷贝(shallow copy):

浅拷贝:是指在赋值过程中只复制一层变量,不会复制深层变量绑定对象的复制过程

1
2
3
4
5
6
7
L = [3.1,3.2]
L1 = [1,2,L]
L2 = L1.copy()
print(L1)
L2[2][0] = 3.14
print(L1)
print(L2)

image-20220720165622852

深拷贝:通常只对可变对象进行复制,不可变对象通常不变

1
2
3
4
5
6
7
8
import copy
L = [3.1,3.2]
L1 = [1,2,L]
L2 = copy.deepcopy(L1)
print(L1)
L2[2][0] = 3.14
print(L1)
print(L2)

image-20220720165654083

=是深拷贝

1
2
3
4
5
A = ['apple']
B = A
B[0] = 'banana'
print(A)
#=是深拷贝,两者ID也相同,修改B会影响A,修改A会影响B

image-20220720170037597

[:]是浅拷贝

1
2
3
4
5
A = ['apple']
B = A[:]
B[0] = 'banana'
print(A)
#[:]是浅拷贝,只拷贝了第一层,修改不会有影响

image-20220720170131080

1.5 列表推导式

列表推导式是用可迭代对象依次生成带有多个元素的列表的表达式

作用:用简易的方法生成列表

语法:

  • [表达式 for 变量 in 可迭代对象]
  • [表达式 for 变量 in 可迭代对象 if 真值表达式]

image-20220720165752801

列表表达式的嵌套:

1
2
3
4
5
[表达式1
For 变量1 in 可迭代对象1 if 真值表达式1
For 变量2 in 可迭代对象2 if 真值表达式2
.....
]
1
print([m + n for m in 'ABC' for n in 'XYZ'])

image-20220721162115498

与其他容器混合使用

1
2
3
4
d = {'x': 'A', 'y': 'B', 'z': 'C' }
print([k + '=' + v for k, v in d.items()])
L = ['Hello', 'World', 'IBM', 'Apple']
print([s.lower() for s in L])

image-20220721162250916

与if-else语句嵌套使用

1
print([x if x % 2 == 0 else -x for x in range(1, 11)])

image-20220721162425804

1.6 列表生成器

image-20220721162702417

创建Lg的区别仅在于最外层的[]()L是一个list,而g是一个generator。

1
2
3
4
g = (x * x for x in range(2))
print(next(g))
print(next(g))
print(next(g))

generator保存的是算法,每次调用next(g),就计算出g的下一个元素的值,直到计算到最后一个元素,没有更多的元素时,抛出StopIteration的错误。

image-20220721162859614

使用for语句调用列表生成器:

1
2
3
g = (x * x for x in range(3))
for n in g:
print(n)

image-20220721163203035

如果一个函数定义中包含yield关键字,那么这个函数就不再是一个普通函数,而是一个generator函数,调用一个generator函数将返回一个generator:

1
2
3
4
5
6
7
def test():
print('step 1')
yield 1
print('step 2')
yield(3)
print('step 3')
yield(5)

image-20220721163435792

调用generator函数会创建一个generator对象,多次调用generator函数会创建多个相互独立的generator。

image-20220721163510830

所以,需要预先定义好generator对象:

image-20220721163558866

1.7 列表解包

将list中每个元素赋值给一个变量

1
2
3
4
name, age, date = ['Bob', 20, '2018-1-1']
print(name)
print(age)
print(date)

image-20220720170329244

使用*:比如我们要计算平均分,去除最高分和最低分,除了用切片,还可以用解包的方式获得中间的数值。

1
2
3
4
5
6
7
list = [1, 2, 2, 'Hi', 'Wow']
head, *Igno, tail = list
print(head)
print(Igno)
print(tail)
first, *new, last = [94, 85, 73, 46]
print(new)

image-20220720170558354

压包和解包混合

1
2
3
4
5
l = [('Bob', '1990-1-1', 60),
('Mary', '1996-1-4', 50),
('Nancy', '1993-3-1', 55),]
for name, *args in l:
print(name, args)

image-20220720170713804

_的用法

当一些元素不用时,用_表示是更好的写法,可以让读代码的人知道这个元素是不要的

image-20220720170843061

1.8 列表迭代

1
2
3
4
from collections.abc import Iterable
print(isinstance('abc', Iterable)) # str是否可迭代
print(isinstance([1,2,3], Iterable)) # list是否可迭代
print(isinstance(123, Iterable)) # 整数是否可迭代

image-20220721161926526

Python内置的enumerate函数可以把一个list变成索引-元素对,这样就可以在for循环中同时迭代索引和元素本身:

1
2
for i, value in enumerate(['A', 'B', 'C']):
print(i, value)

image-20220721161958054

2.元组tuple

2.1 元组生成

  • 元组是不可改变的序列,同list一样,元组可以存放任意类型的元素,一旦元组生成,则它不可以改变
  • 元组的表达方式:用小括号( )括起来,单个元素括起来用逗号(,),区分是单个对象还是元组,创建空元组的字符值t=( )
  • 元组的构造函数 tuple
    • tuple( )生成一个空的元素,等同于( )
    • tuple(iterable)用可迭代对象生成一个元组
1
2
3
4
t = tuple()   
t = tuple(range(10))
t = tuple('hello')
t = tuple([1,2,3,4])

image-20220720171109755

  • 元组的算术运算:+ += * *= < <= > >= == !=规则与列表完全相同
  • in/in not索引取值/切片取值—规则与列表完全相同
  • 区别:元组是不可变对象,不支持索引赋值和切片赋值

2.2 元组的方法

1
2
3
4
t.index(v[,begin[,end]])
#用于获取元组中v所在的索引位置
t.count(v)
#用于获取元组中v的个数

可用于序列的函数:len,max,min,sum,all,any

三个构造函数:

str(obj) list(iterable) tuple(iterable)用于创建相应的对象

其他函数:

1
2
reversed(seq)返回反向顺序的可迭代对象
sorted(iterable,reversed=False)返回已经排序的列表

3.字典dict

  1. 字典是一种可变的容器,可以储存任意类型的数据
  2. 字典中的每个数据都是用’键’(key)进行索引,而不像序列可以用下标进行索引
  3. 字典的数据没有先后顺序,字典的存储是无序的
  4. 字典中的数据以键(key)-值(value)对进行映射存储
  5. 字典的键不能重复,而且只能用不可变类型作为字典的键

字典的字面值表示方式:{ }括起来,以冒号:分隔键值对,各键值对用分号隔开。

3.1 字典的构造

创建空字典:

1
d={ }

创建非空的字典:

1
2
3
d = {'name':'tarena';'age':15}
d = {'姓名':'小张'}
d = {1:'壹',2:'贰'}
  • len()函数是统计键值对的个数
  • 集合之间的显示是随机的,输出时不一定按照原有的顺序进行输出

字典的构造函数 dict

dict( )创建一个空字典,等同于{ }

dict(iterable)用可迭代对象初始化一个字典

dict(**kwargs)关键字传参形式生成一个字典

1
2
d = dict( )   
d = dict(name = 'tarena',age = 15)

只要是有两个数之间的对应关系都可以输出,分别作键和值

1
2
3
4
d = dict(("AB","CD"))
print(d)
c = dict(("AB","CD",[1,2],(3,4)))
print(c)

image-20220720171621028

字典的键是不可变类型:int float complex bool str tuple frozenset(字节串) bytes(字节串)

3.2 字典的基本操作

1)用[]运算符可以获取字典内的’键’对应的’值’

语法: 字典[键]

1
2
3
d = {'first':123, 'second':456}
print(f"My address is {d['first']}")
# 此处需要对引号进行转义

image-20220720171700056

2)添加/修改字典元素

  • 字典[键]=表达式
  • 当键存在时就修改键对应的值,如果不存在则创建键值对

3)del语句删除字典中的元素

语法:del 字典[键]

字典的方法:

1
2
3
4
5
6
7
8
d.clear()清空字典
d.pop(key)移除键,同时返回键所对应的值
d.copy()返回字典d的副本,只复制一层(浅拷贝)
d.update(d2)将d2合并到d中,如果键相同,则此键的值取d2的作为新值
d.get(key,default[])返回键key所对应的值,如果没有此键,返回default
d.keys()返回可迭代的dict_keys集合对象
d.values()返回可迭代的dict_values值对象
d.items()返回可迭代的dict_items对象

字典推导式:字典推导式是用可迭代对象依次生成字典内元素表达式

语法:{键值表达式:值表达式 for 变量 in 可迭代对象 [if 真值表达式]}

注:[ ]内的内容可以省略

1
2
3
L=['tarena','xiaozhang','xiaowang']
d={x:len(x) for x in L}
print(d)

image-20220720171757489

1
2
3
4
5
6
7
8
9
10
11
12
13
14
a = dict();
a[0] = (1,2,3)
a[1] = {2,3,5}
a["AB"] = "12"
print(a)
print(a.items())
print(a.keys())
print(a.values())
for k in a:
print(k,a[k])
for k in a.keys():
print(k,a[k])
for k,v in a.items():
print(k,v)

image-20220720171833065

格式化输出

1
2
3
4
library = [('Author','Topic','Pages'),('Alex','Soccer',200),('Raj','Golf',18),('Tony','Tik Tok',1005)]
for book in library:
print(f'{book[0]:10} {book[1]:15} {book[2]:.>10}')
# 格式化输出

image-20220720171904704

4.集合set

  • 集合是可变的容器,集合内的对象是唯一的,集合是无序的存储结构,集合中的数据没有先后关系,集合内的元素必须是不可变的对象,集合是可以迭代的,集合是相当于只有键没有值的字典(键则是集合的数据)
  • 创建空的集合:set()
  • 创建非空集合:s={1,2,3}
  • 集合的构造函数 set
    • set()创建空集合
    • set(iterable)用可迭代对象创建一个新的集合对象

4.1 集合的运算

交集,并集,补集,子集,超集

1
2
3
4
5
6
7
8
9
10
&用于生成两个集合的交集
|用于生成两个集合的并集
-用于生成两个集合的补集s1-s2生成属于s1不属于s2的集合
^用于生成两个集合的对称补集s3=s1^s2等价于s3=(s1-s2)|(s2-s1)
<判断一个集合是两一个集合子集
>判断一个集合是另一个集合的超集
==判断集合相同
!=判断集合不同
in判断是否存在于集合中
可用于集合中的函数:len(x),max(x),sum(x),any(x),all(x)

4.2 集合的处理方法

1
2
3
4
5
6
7
8
9
10
11
12
s.add(e)向集合中添加一个新元素e,如果元素已经存在,则不添加
s.add(x)如果x不在s中,把x增加到s中
s.discard(x)移除s中的元素x,如果x不在集合s中,不报错
s.remove(x)移除s中的元素x,如果x不在集合中,会出现keyerror 的报错
s.clear()移除s中所有的元素
s.pop()随机返回s中的一个元素,更新s,若s为空则返回keyerror的报错
s.copy()返回集合s的一个副本
s.pop()删除集合中的随机元素,如果集合为空,返回keyerror 的报错
s.update(s2)用s和s2的全集更新变量s
s.difference(s2)返回存在于s,不存在于s2中的元素
s.isdisjoint(s2)如果s和s2的交集为空返回true,否则返回false
s.issubset(s2)如果s和s2交集非空返回true,否则返回false

4.3 集合推导式

用可迭代对象来创建(生成)集合表达式

语法:

1
{表达式 for 变量 in 可迭代对象 [if 真值表达式]}

4.4 固定集合

固定集合:frozenset

固定集合是不可变的,无序的,含有唯一元素的集合

作用:固定集合可以作为字典的键,也可以作为集合的值

1)创建空的固定集合 fs=frozenset()

2)创建非空的固定集合 fs=frozenset()

构造函数:frozenset() frozenset(可迭代对象)(返回固定集合)

【案例制作】

小练习:模拟一个点名系统,已知全班同学的名单,随机打印学生的名字,点名结束后打印未到名单

1
2
3
4
5
6
7
8
9
10
11
names=['tom','Jerry','spike','tyke']
s=set(names)#生成集合,乱序
l=[]#代表未到的人的列表
for n in s:
info=n+"已到?(y):"
r=input(info)
if r!='y':
l.append(n)#使用append函数可以在列表最后增加一个元素
print("未到名单如下:")
for n in l:
print(n,end=' ')

image-20220720172749209