大纲
- 集合类型
- 列表
- 元组
- 字典
- 集合
- 循环
- 练习
集合类型
基础语法中介绍的几种 python 的基础类型都属于 数值类型
。
另外一种基础类型是 集合类型
,主要包括 列表
、 元组
、 字典
、 集合
。
其中 列表
和元组
是一种 序列
。 序列
是一种将一串 元素
按顺序组合在一起的 数据结构
。
序列的特点是拥有 索引操作
与切片操作
。
索引操作 是从序列中通过编号获得其中的一个元素,语法是中括号 [编号]
。
切片操作 是获取一部分序列,语法为 [编号 1: 编号 2]
。
回忆 字符串
,是不是也有相同的操作,获取其中某个或某段字符。
所以字符串其实也是一种序列,其元素就是单个字符。
列表
列表
是一种 有序
的序列
,其 元素
可以是 任意类型
,编号从0
开始到 长度 -1
结束。
创建一个列表 :Python 中使用 中括号 []
来表示列表。注意与索引切片区分。
name_list = ['Green', 'Lucy', 'Lily'] # 字符串列表
score_list = [98, 67, 80] # 整数列表
x_list = ['hello', 98, 2.15, True] # 任意类型列表
y_list = [score_list, name_list] # 列表的列表
获取列表长度:len
。
print(len(name_list)) # 列表长度
索引与切片:
print(score_list[1]) # 索引,返回元素
print(x_list[0:1]) # 切片,返回列表
输出:
如何理解列表的列表?
y_list = [score_list, name_list]
列表中可以放任意类型的数据,放一个序列类型肯定是没有问题的。
专业的说法是 二维列表
,当然还可以继续嵌套形成 多维列表
。
访问方式:
print(y_list[1][2]) # 访问多维列表
通过第一个 []
获得第一维的列表,再用 []
就可以得到第二维的数据了。
等价于
_name_list = y_list[1]
print(_name_list[2])
修改元素:直接通过赋值就可以修改其中的元素。
name_list[2] = 'Kate'
逻辑判断:in
,not in
判断列表中是否存在某个元素。
if 'Green' in name_list:
print('Green is here')
if 'Lucy' not in name_list:
print('Lucy is not here')
加法与乘法 :
加号(+
)会将两个列表组合起来产生一个新列表。
# 加法
x = [1, 3, 2]
y = [4, 6, 5]
z = x + y
print(x + y)
输出:
乘号(*
)则会将原列表进行复制,产生新列表。
# 乘法
x = [1, 2, 3]
z = x * 3
print(z)
输出:
最大值与最小值:max
、min
。
x = [1, 2, 3]
print(max(x))
print(min(x))
输出:
如果列表内的元素必须是 可比较
的。试试字符串列表能不能用?
排序:sort
。将列表内的元素从小到大进行排序。
# 排序
x = [1, 2, 4, 5, 3, 2]
x.sort()
print(x)
输出:
翻转列表:reverse
。把列表进行翻转,后面到前面。
x.reverse()
将上面排序好的进行翻转就得到
索引 :index
,获得某个元素在列表中 第一次
出现的 位置
。
x = [1, 2, 3, 2]
i = x.index(2)
print(i)
2 第一次出现在位置 1,所以输出 1。当元素 不存在
时,该方法会 报错
。
可以先判断是否存在,再做索引。或者使用后面介绍的 try
、except
来处理。
if 9 in x:
i = x.index(9)
print(i)
统计元素个数:count
。
x = [1, 2, 4, 5, 3, 2]
print(x.count(2))
x 列表中元素 2 出现了 2 次,所有该方法返回 2。
尾部添加 :append
、extend
。
两个都是在尾部添加,区别在于 append
添加的是 元素
,extend
添加的是 列表
。
x = [1, 2, 3]
x.append(100)
print(x)
x.extend([200, 300])
print(x)
输出:extend
的效果相当于
x = x + [200, 300]
插入元素:insert
。在列表的某个位置插入某个元素,insert(位置,元素)
x = [1, 2, 3]
x.insert(0, 0)
x.insert(2, 100)
print(x)
输出:
x 列表先在位置 0(即列表开头)插入了 0,然后又在位置 2 插入了 100。
删除 :remove
,del
,pop
,clear
。remove
删除 第一个出现
的该元素,如果 不存在
时与 index
一样会 报错
。del
则是根据 索引位置
进行删除,当索引 超出范围
时会 报错
。pop
会删除 最后
一个元素,并将其 返回
。clear
删除 所有
列表中元素。
x = [1, 2, 3, 2]
x.remove(2) # 删除第一个 2 元素
del x[1] # 删除位置 1 的元素
p = x.pop() # 删除最后一个 2,同时 p 被赋值 2
x.clear() # 删除所有元素
元组
元组
与列表
是一个的 区别
就是元组是一种 不可变序列
,其他都与列表一样。
元组拥有序列的通用操作,但会改变序列的方法都不存在。
创建一个元组 :Python 中使用 括号 ()
来表示元组。单只有一个元素时,要加一个 逗号
。
a = (1,) # 只有一个元素的元组
b = (1, 3, 4) # 元组
序列通用操作:
print(len(a)) # 长度
print(b[1]) # 索引
print(b[0:2]) # 切片
print(max(b)) # 最大值
print(min(b)) # 最小值
print(2 in b) # in
输出:
元组与列表的转换:list
、tuple
。
tuple([1, 2, 3]) # 转换为元组
list((1, 2, 3)) # 转换为列表
拆包 :拆包是将元组或列表中的 所有元素
逐个 赋值
给多个变量
。
x = ('a', 'b', 'c')
a, b, c = x
print(a, b, c)
输出:
a,b,c 三个变量用 逗号
隔开,并按顺序被赋值上 x 元组中的三个值。
变量的数量必须与元组的 长度一样
。
字典
字典 是一种 无序
的结构,同样可以放入 任意类型
元素。
与 列表
使用 0,1,2…进行 有序
索引不同,字典
使用 自定义
的关键字
进行索引。
key-value 结构 :key
代表用来索引的 关键字
,value
代表存储的 元素
。【 键值对
】
创建一个字典 :使用 大括号 {}
包裹字典,每个 键值对
用逗号
隔开,键值对
中用 冒号
分隔 key
与value
,前面的是 key,后面的是 value。
user = {
'name': 'Green',
'age': 12,
'gender': 'male'
}
写成一行
user = {'Green': 80, 'Lily': 90, 'Lucy': 76}
也是可以的,但大部分情况分行书写会比较清晰。
如何取值 :同样是通过 []
来进行,只不过将列表里的编号换成 key
值就可以取到 value。
print(user['name'])
当 key不存在
时,会 报错
。
安全取值 :get
,如果 key 不存在时,使用get
方法可以 避免报错
,并返回一个 空值 None
。
address = user.get('address') # 返回 None,因为没有 address 这个 key
name = user.get('name') # 返回 Green
添加与修改:直接赋值。
user['address'] = 'china' # 添加一个 address 键值对
user['age'] = 18 # age 被修改为 18
删除:del
。
del user['gender'] # 删除了 gender 这个键值对
清空:clear
。
user.clear() # 清空了所有键值对
判断存在 key:in
。
if 'age' in user: # 判断 age 是否在 user 里面
print(user['age'])
获得字典的所有内容:keys
、values
、items
。
print(user.keys()) # 获得所有 key 值
print(user.values()) # 获得所有 value 值
print(user.items()) # 获得所有键值对
输出:
输出的值并不是列表,可以用 list
方法转换为列表,方便使用。
复杂结构 :通过 字典
和列表
的互相嵌套
,就能实现实际开发中常用的结构。
users = [{'name': 'Green', 'age': 12, 'like': ['apple']},
{'name': 'Lucy', 'age': 13, 'like': ['apple', 'pear']},
{'name': 'Lily', 'age': 11, 'like': ['orange', 'melon']}
]
获得某个用户的第一个喜好。
print(users[1]['like'][0])
通过多个 []
的提取,最后就提取到了用户 1【Lucy】的第一个喜好。
集合
集合 是一组 key
组成的数据,与 字典
的区别
在于 没有 value
,
与 列表
的区别
在于每个元素 key不可重复
。
在数学上可以进行 交集
、 并集
、 差集
等运算,是一种在特定场合很方便的数据结构。
创建集合 :与字典一样,使用 大括号 {}
表示集合,但不需要有 value。
set1 = {'apple', 'orange', 'melon'}
set2 = {'apple', 'pear'}
列表去重 :使用set
方法将列表 转换
为集合,可以很方便的对列表去重。
print(set([1, 3, 3, 4])) # 列表去重
print(set('class')) # 字符串也是一种序列
输出:
输出的结果自动删除了重复的值,然后还可以再用 list
转换为列表,就是去重后的列表了。
交集 :set1 &
set2,计算两个集合中相同的元素。
并集 :set1 |
set2,计算两个集合所有的不重复元素。
差集 :set1 –
set2,计算 set1 中有,但 set2 中没有的元素。
对称差集:set1 ^
set2,计算只存在于 set1 或 set2 中的元素。
set1 = {'apple', 'orange', 'melon'}
set2 = {'apple', 'pear'}
print(set1 & set2) # 交集
print(set1 | set2) # 并集
print(set1 - set2) # 差集
print(set1 ^ set2) # 对称差集
输出:
添加元素:add
。
s = {'apple', 'orange'}
s.add('pear')
删除元素:remove
、discard
、pop
、clear
。
s.remove('apple') # 如果不存在该元素,会报错。s.discard('apple1') # 更安全的删除,即使不存在也不报错
x = s.pop() # 随机删除集合是中的一个元素,并返回它
s.clear() # 删除集合中的所有元素
子集与超集的判断:issubset
、issuperset
。
set1 = {'a', 'b', 'c'}
set2 = {'a'} # set2 是 set1 的子集,set1 是 set2 的超集
set2.issubset(set1) # 返回 True
set1.issuperset(set2) # 返回 True
循环
循环 语句用于处理具有 重复性
的工作,经常用于处理列表、字典等结构。
如一个列表中有几十万个元素,这时候就需要用循环来 遍历
所有元素。
遍历 是一种从集合中逐个获取元素的操作。
for 循环:for
、in
。
names = ['Green', 'Lucy', 'Lily']
for name in names:
print('Happy Birthday, {}'.format(name))
输出:for
打头开始一个循环,in
后面的 names
表示要遍历的列表。for
后面的 name
是一个 临时变量
,用来 存储
遍历过程中的每个 元素
。
从0
到 N-1
的元素按顺序依次 赋值
给临时变量
,并 重复执行
下面的 代码块
N 次。(N 等于列表的长度)
编写一个程序,计算列表中所有元素的总和。
numbers = [10, 53, 45, 44, 907] # 要计算的列表
answer = 0 # 总和初始化为 0
for i in numbers: # 开始循环
answer = answer + i # 逐个相加
print(answer)
每次循环 i
都会被 赋值
为 numbers 里的一个值。
将当前的 answer 加上 i,并将结果赋值给 answer。每次循环
都更新了 answer,当 循环结束
时就是列表的总和了。sum
方法,同样也可以完成这个功能,可以将结果进行对比。
sum(numbers)
这里我们初步了解到了方法到底在做什么。
停止循环 :break
。
在 for 循环代码块中出现 break,就会停止 这个 for 循环
。
一般我们会与 条件判断
一起使用,实现 满足条件
后停止循环。
下面我们一起实现一个 index
功能。【返回第一次出现的位置,不存在时返回 -1】
numbers = [10, 53, 45, 44, 907]
i = 0 # 记录当前遍历到的位置
index = -1 # 结果默认为 - 1 不存在
for number in numbers:
if number == 53: # 满足条件
index = i # 赋值位置
break # 停止循环
i = i + 1 # 位置 +1
print(index)
这里的 i 记录了当前遍历到的位置,所以在每次循环执行的最后要加 1。
如果你打印出 i 的值,会发现 i 停止在了满足条件的位置,即循环停止了。
中断循环 :continue
。
在循环中出现 continue
,就会停止该次循环,马上进行 下一轮
循环。
下面我们还是实现一个求和的功能,但如果数字大于 100 时不计算在内。
numbers = [10, 53, 45, 44, 907]
answer = 0
for i in numbers:
if i > 100:
continue # 马上开始下一个循环
answer = answer + i
print(answer)
当大于 100 时,就跳过,不进行相加。
也许你已经发现其实不用 continue
也可以实现这个功能。
if i <= 100:
answer = answer + i
所以 continue 的出镜率并不高,一般在逻辑异常复杂时非常好用。
while 循环 :while
。while
循环是根据 条件判断
来是否 继续循环
的。
names = ['Green', 'Lucy', 'Lily']
i = 0 # 索引位置从 0 开始
while i < len(names): ~~~~# 条件为 True 时,继续循环
name = names[i] # 通过索引获得元素
print('Happy Birthday, {}'.format(name))
i = i + 1 # 索引 +1
while
后面的 条件语句
就是要判断的内容,为 True
时循环 继续
,为False
时循环 停止
。
这是我们写的第一个 for 循环的 while 版本。条件为索引值小于列表长度。while
同样支持 break
和continue
。
while 和 for 循环是基本等价的不同写法,根据需要选择更方便的写法。
# 无限循环
while True:
print(1)
range:生成一个整数序列。在 for 循环中常用。
for i in range(10): # 0 到 9 的序列
print(i)
range(3, 10) # 3 到 9 的序列
range(3, 10, 2) # 3,5,7,9 步长为 2 的序列
range
可以生成 从 a 到 b
,且 步长为 n
的 整数序列
。
for 循环的 range 版本:
names = ['Green', 'Lucy', 'Lily']
for i in range(len(names)):
name = names[i]
print('Happy Birthday, {}'.format(name))
这里使用 len(names)
来生成 全部的索引
,经常处理列表时有需要索引值时可以这样做。
循环的嵌套:
for i in range(1, 10):
for j in range(1, 10):
print('{} * {} = {}'.format(i, j, i*j))
九九乘法表的生成。
上面的乘法表有个问题,就是生成了 1 * 2 和 2 * 1 两个,这时我们通过加入 continue
解决。
for i in range(1, 10):
for j in range(1, 10):
if j < i:
continue
print('{} * {} = {}'.format(i, j, i*j))
break
和 continue
在循环中只作用于它 所处的循环
,这个要特别注意。
字典的循环 :字典类型同样可以用循环来处理。
1、通过keys
循环遍历所有key
。
user = {'name': 'Green', 'age': 12, 'address': 'china'}
for key in user.keys():
print('{} : {}'.format(key, user[key]))
2、通过 items
循环遍历所有 键值对
。
for key, value in user.items():
print('{} : {}'.format(key, value))
与之前的 for 循环不一样的地方就在于 items
方法返回的列表中元素是一个 元组
【键值对】。
所以在接收时就要用 key
和value
两个变量去将其 拆包
,这样就可以同时遍历到 key 和 value。
练习
编写一个获得列表中最大值的程序。
编写一个获得列表中最小值的程序。
编写一个计算列表所有值的平均值的程序。
github: https://github.com/lvancer/course_python