容器类型
Posted Python3技术笔记
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了容器类型相关的知识,希望对你有一定的参考价值。
6. 容器类型 - 3
字典
引入
场景一:
声明一个列表
nameList = [\'张三\', \'李四\', \'王五\']
如果发现 "李四"
这个名字写错了,通过下标修改
nameList[1] = \'赵六\'
但是如果列表元素的顺序发生了变化,如下列代码
nameList = [\'张三\', \'王五\', \'李四\']
此时就必须需要修改下标,才能完成姓名的修改
nameList[2] = \'赵六\'
问:有没有方法,既能存储多个数据,还能在访问元素的很方便就能够定位到需要的那个元素呢?
场景二:
学生信息列表,每个学生信息包括学号、姓名、年龄等,如何从中找到某个学生的信息?
students = [[1001, "张三", 24], [1002, "李四", 23], [1005, "王五",24], ...]
假如上述列表有100个人的信息,此时会发现想要找到某个人的信息虽然我们可以数数0、1、2、。。。。但这也太麻烦了
问:有没有更方便的方式呢?
通过上面的2个场景的描述,发现虽然列表可以很轻松的实现数据的正删改查,但当多个数据时,想要快速定位到某个数据就会很不方便
基于此原因,Python发明了一种特殊的下标
,可以快速的找到想要的数据
拥有这种特殊下标的数据类型就是字典
基本使用
定义格式
key: value, key2: value ...
说明:
key
可以理解为:我们自己可以定义的下标value
可以理解为:我们要存储的真正的数据- 字典只要存储一个数据,就必须用
key: value
(我们常称为键值对)组成
代码示例
定义一个字典,存储顾安老师的信息
teacher_info = \'name\': \'顾安\', \'age\': 18, \'home\': \'湖南省长沙市\'
如果感觉一行太长,写不开,可以用如下的方式
teacher_info =
\'name\': \'顾安\',
\'age\': 18,
\'home\': \'湖南省长沙市\'
说明:
- 字典能够存储多个数据
- 列表中找某个元素时,是根据下标进行的,字典中找某个元素时,是根据\'key\'(就是冒号:前面的那个值,例如上面代码中的\'name\'、\'home\'、\'age\')
- 字典的每个元素由2部分组成,
键:值
根据 key 访问 value
teacher_info =
"name": "顾安",
"age": 18,
"home": "湖南省长沙市"
print(teacher_info[\'name\']) # 获取姓名
print(teacher_info[\'age\']) # 获取年龄
print(teacher_info[\'home\']) # 获取住址
运行结果:
顾安
18
湖南省长沙市
遍历字典(keys、values、items)
keys() 方法
遍历字典的键(key)
teacher_info =
"name": "顾安",
"age": 18,
"home": "湖南省长沙市"
for key in teacher_info.keys():
print(key)
运行结果:
name
age
home
values() 方法
遍历字典的值(value)
teacher_info =
"name": "顾安",
"age": 18,
"home": "湖南省长沙市"
for val in teacher_info.values():
print(val)
运行结果:
顾安
18
湖南省长沙市
items() 方法
遍历字典的项(元素)
teacher_info =
"name": "顾安",
"age": 18,
"home": "湖南省长沙市"
for item in teacher_info.items():
print(item)
运行结果:
(\'name\', \'顾安\')
(\'age\', 18)
(\'home\', \'湖南省长沙市\')
字典的常见操作
数据查询 - 普通方式
teacher_info =
"name": "顾安",
"age": 18,
"home": "湖南省长沙市"
print(teacher_info[\'QQ\']) # 当前字典不存在QQ这个键
运行结果:
Traceback (most recent call last):
File "/Users/poppies/Desktop/字典.py", line 8, in <module>
print(teacher_info["QQ"])
KeyError: \'QQ\'
数据查询 - get 方式
在我们不确定字典中是否存在某个键而又想获取其值时,可以使用get
方法,还可以设置默认值:
teacher_info =
"name": "顾安",
"age": 18,
"home": "湖南省长沙市"
print(teacher_info.get(\'QQ\', \'当前字典不存在QQ这个key\')) # 当前字典不存在QQ这个键
运行结果:找不到指定的key则使用默认值,程序不会因为key的不存在而崩溃
当前字典不存在QQ这个key
数据修改
字典的每个元素中的数据是可以修改的,只要通过key找到,即可修改
info = \'name\': \'班长\', \'id\': 100, \'sex\': \'男\', \'address\': \'中国北京\'
new_id = input(\'请输入新的学号:\')
info[\'id\'] = int(new_id)
print(\'修改之后的id为: %d\' % info[\'id\'])
运行结果:
请输入新的学号:1010
修改之后的id为: 1010
数据增加
新的key
以及value
就表示添加一个新的键值对
即:如果在使用 变量名[\'键\'] = 数据
时,这个“键”在字典中不存在,那么就会新增这个元素。
info = \'name\': \'班长\', \'id\': 100, \'sex\': \'男\', \'address\': \'中国北京\'
print(info)
info[\'web_address\'] = "www.tulingxueyuan.com" # 添加一个新的键值对
print(info)
执行结果:
\'name\': \'班长\', \'id\': 100, \'sex\': \'男\', \'address\': \'中国北京\'
\'name\': \'班长\', \'id\': 100, \'sex\': \'男\', \'address\': \'中国北京\', \'web_address\': \'www.tulingxueyuan.com\'
数据删除
对字典进行删除操作,有一下几种:
del
clear()
del 删除指定的元素
示例代码:
teacher_info = \'name\': \'顾安\', \'age\': 18, \'home\': \'湖南省长沙市\'
print(teacher_info)
del teacher_info[\'home\']
print(teacher_info)
运行结果:
\'name\': \'顾安\', \'age\': 18, \'nome\': \'湖南省长沙市\'
\'name\': \'顾安\', \'age\': 18
del 删除整个字典
示例代码:
teacher_info = \'name\': \'顾安\', \'age\': 18, \'home\': \'湖南省长沙市\'
print(teacher_info)
del teacher_info
print(teacher_info)
执行结果:
\'name\': \'顾安\', \'age\': 18, \'nome\': \'湖南省长沙市\'
Traceback (most recent call last):
File "/Users/poppies/Desktop/字典常见操作.py", line 7, in <module>
print(teacher_info)
NameError: name \'teacher_info\' is not defined
clear 清空整个字典元素
示例代码:
teacher_info = \'name\': \'顾安\', \'age\': 18, \'home\': \'湖南省长沙市\'
print(teacher_info)
teacher_info.clear()
print(teacher_info)
运行结果:
\'name\': \'顾安\', \'age\': 18, \'nome\': \'湖南省长沙市\'
推导式
引入
推导式:就是一种能够快速生成数据的方式
例如,想要快速生成由1~20内所有偶数数组成的列表,就可以用"推导式",代码如下:
[x for x in range(1, 21) if x % 2 == 0]
运行结果如下:
[2, 4, 6, 8, 10, 12, 14, 16, 18, 20]
分类
推导式,根据最终要生成的数据,简单划分为
- 列表推导式
- 集合推导式
- 字典推导式
注意:没有元组推导式,而是生成器(在Python高级进阶课程中在学习)
列表推导式
列表推导式:一种可以快速生成列表的方式
代码格式:
[变量 for 变量 in 可迭代对象]
基本使用:
案例一:
In [1]: a = [x for x in range(4)]
In [2]: a
Out[2]: [0, 1, 2, 3]
In [3]: a = [x for x in range(3, 4)]
In [4]: a
Out[4]: [3]
In [5]: a = [x for x in range(3, 19)]
In [6]: a
Out[6]: [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18]
In [7]: a = [x for x in range(3, 19, 2)]
In [8]: a
Out[8]: [3, 5, 7, 9, 11, 13, 15, 17]
案例二:列表推导式中用到了 if
注意:列表推导式如果for
中用到了if
,for
不用写:
In [9]: a = [x for x in range(3, 10) if x % 2 == 0]
In [10]: a
Out[10]: [4, 6, 8]
In [11]: a = [x for x in range(3, 10) if x % 2 != 0]
In [12]: a
Out[12]: [3, 5, 7, 9]
案例三:在列表推导式中使用两个 for
循环
In [13]: a = [(x, y) for x in range(1, 3) for y in range(3)]
In [14]: a
Out[14]: [(1, 0), (1, 1), (1, 2), (2, 0), (2, 1), (2, 2)]
案例四:在列表推导式中使用三个 for
循环
In [15]: a = [(x, y, z) for x in range(1, 3) for y in range(3) for z in range(4, 6)]
In [16]: a
Out[16]:
[(1, 0, 4),
(1, 0, 5),
(1, 1, 4),
(1, 1, 5),
(1, 2, 4),
(1, 2, 5),
(2, 0, 4),
(2, 0, 5),
(2, 1, 4),
(2, 1, 5),
(2, 2, 4),
(2, 2, 5)]
练习
请写出一段 Python 代码实现分组:一个 list 里面的元素,比如 [1,2,3,...100]
变成 [[1,2,3],[4,5,6]....]
参考答案:
a = [x for x in range(1,101)]
b = [a[x:x+3] for x in range(0, len(a),3)]
print(b)
集合推导式
集合推导式:一种快速生成集合的方式
示例代码:
In [5]: a = x for x in range(1, 21) if x % 2 == 0
In [6]: type(a)
Out[6]: set
In [7]: a
Out[7]: 2, 4, 6, 8, 10, 12, 14, 16, 18, 20
集合推导式中也可以用if
等,与列表推导式在格式上很类似,这里就不做过多的介绍,请类别列表推导式进行学习
字典推导式
字典推导式:一种快速生成字典的方式
案例一:快速生成一个1~10内key为某个数此时value为平方的字典
x: x ** 2 for x in range(1, 11)
运行效果:
1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81, 10: 100
案例二:快速生成一个1~10内key可以1时value为2,key为2时value3....依次类推的字典
x: (x + 1) for x in range(1,11)
运行效果:
1: 2, 2: 3, 3: 4, 4: 5, 5: 6, 6: 7, 7: 8, 8: 9, 9: 10, 10: 11
练习
编写代码用推导式,实现如下效果(列表中嵌套字典)
[1: 1,
2: 4,
3: 9,
4: 16,
5: 25,
6: 36,
7: 49,
8: 64,
9: 81,
10: 100]
参考代码:
[x: x ** 2 for x in range(1, 11)]
拆包
引入
拆包:是一种快速提取数据的方式
例如,有一个元组(11, 22, 33, 44)
想快速的提取每个元素且赋值给num1, num2, num3, num4
这4个变量
普通的做法,较为繁琐:
nums = (11, 22, 33, 44) # 定义一个元组
num1 = nums[0] # 通过下标来提取
num2 = nums[1] # 通过下标来提取
num3 = nums[2] # 通过下标来提取
num4 = nums[3] # 通过下标来提取
拆包的方式,可以见非常简洁:
num1, num2, num3, num4 = (11, 22, 33, 44) # 一行代码搞定
列表拆包
示例:
a, b = [11, 22]
print(a)
print(b)
效果:
11
22
元组拆包
示例:
a, b = (11, 22)
print(a)
print(b)
效果:
11
22
集合拆包
示例:
a, b = 11, 22
print(a)
print(b)
效果:
11
22
字典拆包
一般用法
a, b = "name": "顾安", "age": 18
print(a)
print(b)
name
age
默认取到的是字典的key,而不是value
常见用法
teacher_info = "name": "顾安", "age": 18
for k, v in teacher_info.items():
print(\'k = %s, v = %s\' % (k, v))
k = name, v = 顾安
k = age, v = 18
注意点
=
右边要拆的数据元素的个数 要 与=
左边存的变量个数相同
错误示例如下:
a, b = [11, 22, 33]
运行结果如下:
ValueError Traceback (most recent call last)
<ipython-input-19-887c339c8076> in <module>
----> 1 a, b = [11, 22, 33]
ValueError: too many values to unpack (expected 2)
经典面试题:交换两个变量的值
方式一:普通方式
a = 4
b = 5
print("交换之前a=%d, b=%d" % (a, b))
# 额外定义一个变量,用来临时使用
c = a
a = b
b = c
print("交换之后a=%d, b=%d" % (a, b))
运行结果:
交换之前a=4, b=5
交换之后a=5, b=4
方式二:巧妙方式
a = 4
b = 5
print("交换之前a=%d, b=%d" % (a, b))
# 巧妙之处(没有用额外的变量)
a = a+b
b = a-b
a = a-b
print("交换之后a=%d, b=%d" % (a, b))
运行结果:
交换之前a=4, b=5
交换之后a=5, b=4
方式三:拆包方式
a = 4
b = 5
print("交换之前a=%d, b=%d" % (a, b))
# Python独到之处
a, b = b, a #
print("交换之后a=%d, b=%d" % (a, b))
执行结果:
交换之前a=4, b=5
交换之后a=5, b=4
说明:
a, b = b, a
首先要计算=
右边b, a
此时他们会被当做一个元组即(b, a)
就相当于(5, 4)
- 然后再将
a, b = (5, 4)
进行计算,此时a为5
,b为4
以上是关于容器类型的主要内容,如果未能解决你的问题,请参考以下文章