本章内容:Python 中的数据容器,如list(列表)、tuple(元组)、str(字符串)、set(集合)、dict(字典)等。
所有相关代码可在https://github.com/hzyao/Python-Cookbook
进行查看。边学习边实操,及时挖掘真美妙!搭配食用或许口味更佳哟!
顺便问一嘴,有多少人和我一样点开 Python 就已经在怀念 R 了!
数据容器:一种可以存储多个元素的数据类型,元素可以是任意类型是数据,如字符串、数字、布尔等。
数据容器类型:list(列表)、tuple(元组)、str(字符串)、set(集合)、dict(字典),它们各有特点,但都满足可容纳多个元素的特性。
列表内的每一个数据,称之为元素。
[]
作为标识,
隔开# 定义列表字面量
["yhz", "lr", "xmy", 666, True]
# 定义列表变量
my_list = ["yhz", "lr", "xmy", 666, True]
print(my_list)
print(type(my_list))
# 定义空列表
o_list = []
o_list = list()
print(o_list)
print(type(o_list))
# 定义一个嵌套的列表
my_list = [[1,2,3], [4,5,6]]
print(my_list)
print(type(my_list))
列表的每一个元素,都有编号,我们称之为下标索引。列表[下标]
即可取出。嵌套列表同样支持下标索引。
从前向后,从 0 开始,依次递增,0,1,2,3…;
从后向前,从 -1 开始,依次递减,-1,-2,-3…。
# 列表的下标索引
my_list = ["yhz", "lr", "xmy", 666, True]
print(my_list[0])
print(my_list[1])
print(my_list[4])
# 倒序取出
print(my_list[-5])
print(my_list[-4])
print(my_list[-1])
# 取出嵌套列表元素
my_list = [[1,2,3], [4,5,6]]
print(my_list[0][1])
注:注意下标索引的取值范围,超出范围无法取出元素,切记从 0 开始。
补充知识
函数 vs. 方法
函数是一个封装的代码单元,可以提供特定功能。
而在 Python 中,如果将函数定义为 class(类)的成员,那么函数就会被称为:方法。
# 函数 def add(x, y): return x + y # 方法 class Student: def add(self, x, y): return x + y
方法和函数功能一样,有传入参数,有返回值,只是方法的使用格式不同。
# 函数的使用 num = add(1, 2) # 方法的使用 student = Student() num = student.add(1, 2)
查询功能
功能:查找某指定元素在列表的下标,如果找不到,报错ValueError
。
语法:列表.index(元素)
index
就是列表对象(变量)内置的方法(函数)。
修改功能
功能:修改特定位置(索引)的元素值,可对指定下标的值进行重新赋值。
语法:列表[下标] = 值
插入功能
功能:在指定下标位置插入指定元素。
语法:列表.insert(下标, 元素)
追加元素
功能:将指定元素追加到列表尾部。
语法:列表.append(元素)
(追加一个),列表.extend(其他数据容器)
(将其他数据容器中的内容取出,依次追加到列表尾部)
删除元素
语法:del 列表[下标]
,列表.pop(下标)
(取出元素并从列表中删除),列表.remove(元素)
(删除某元素在列表中的第一个匹配项)
清空列表
语法:列表.clear()
统计某元素在列表中的数量
语法:列表.count(元素)
# 列表常用操作
## 查询元素下标
my_list = ["yhz", "lr", "xmy", 666, True]
my_list.index("lr")
## 修改元素
my_list[2] = "xiaomanyao"
print(my_list)
## 插入元素
my_list.insert(1, "loves")
print(my_list)
## 追加元素
my_list.append("耶")
print(my_list)
## 追加一批元素
add_list = [1,2,3]
my_list.extend(add_list)
print(my_list)
## 删除元素
del my_list[9]
print(my_list)
## 从列表中取出元素并将其删除
delete = my_list.pop(8)
print(my_list)
print(delete)
## 删除某元素在列表中的第一个匹配项
my_list.remove(1) # 豁,1 就是 True 哈!帅的!
print(my_list)
## 清空列表
my_list.clear()
print(my_list)
## 统计某元素在列表中的数量
my_list = ["yhz", "lr", "xmy", 666, True, "lr"]
count = my_list.count("lr")
print(count)
## 统计列表中全部元素数量
count = len(my_list)
print(count)
总结:
列表.append(元素)
:向列表中追加一个元素;
列表.extend(容器)
:将数据容器的内容依次取出,追加到列表尾部;
列表.insert(下标,元素)
:在指定下标处,插入指定的元素;
del 列表[下标]
:删除列表指定下标元素;
列表.pop(下标)
:删除列表指定下标元素;
列表.remove(元素)
:从前向后,删除此元素第一个匹配项;
列表.clear()
:清空列表;
列表.count(元素)
:统计此元素在列表中出现的次数;
列表.index(元素)
:查找指定元素在列表的下标找不到报错 ValueError;
len(列表)
:统计容器内有多少元素。
列表特点:
遍历:将容器内元素依次取出并处理,称为遍历操作。可使用 while 或 for 循环。
while 循环和 for 循环的对比
在循环控制上:
在无限循环上:
在使用场景上:
# while 循环遍历列表
my_list = ["yhz", "lr", "xmy", 666, True, "lr"]
def list_while(data):
index = 0
while index < len(data):
element = data[index]
print(element)
index += 1
list_while(my_list)
# for 循环遍历列表
my_list = ["yhz", "lr", "xmy", 666, True, "lr"]
def list_for(data):
for element in my_list:
print(element)
list_for(my_list)
# 练习:遍历取偶数
list = [1,2,3,4,5,6,7,8,9,10]
new_list = []
i = 0
while i < len(list):
if list[i] % 2 == 0:
new_list.append(list[i])
i += 1
print(new_list)
for i in list:
if i % 2 == 0:
new_list.append(i)
print(new_list)
元组同列表一样,可以封装多个不同类型的元素在内,最大的不同点在于:元组一旦完成定义,就不可修改(若是元组中嵌套 list,则 list 中元素可修改)。
元组使用()
定义,且使用,
隔开各个数据,数据可以是不同数据类型,同样支持嵌套,且支持下标索引,写法相同。
注:元组只有一个数据,这个数据后面要添加逗号,否则不是元组类型。
# 定义元组字面量
("yhz", "lr", "xmy", 666, True)
# 定义元组变量
my_tuple = ("yhz", "lr", "xmy", 666, True)
print(my_tuple)
print(type(my_tuple))
# 定义空元组
o_tuple = ()
o_tuple = tuple()
print(o_tuple)
print(type(o_tuple))
# 定义单个元素的元组,切记后面加逗号
single_tuple = ("hello",)
type(single_tuple)
index()
:查找某个数据,如果数据存在返回对应的下标,否则报错;
count()
:统计某个数据在当前元组出现的次数;
len(元组)
:统计元组内的元素个数。
# 元组的常用操作
my_tuple = ("yhz", "lr", "xmy", 666, True, "lr")
## 查找元素对应下标
my_tuple.index(666)
## 统计元素在当前元组中出现的次数
my_tuple.count("lr")
## 统计当前元组内元素个数
len(my_tuple)
# 元组的遍历
my_tuple = ("yhz", "lr", "xmy", 666, True, "lr")
index = 0
while index < len(my_tuple):
element = my_tuple[index]
print(element)
index += 1
for element in my_tuple:
print(element)
# 元组中嵌套列表,列表中元素可修改
my_tuple = (["yhz", "lr", "xmy"], 666, True, "lr")
my_tuple[0][2] = "xiaomanyao"
my_tuple
字符串我们已经很熟悉啦!简单介绍!
字符串是字符的容器,一个字符串可以存放任意数量的字符,只可以存储字符串,可使用下标索引,同样可遍历。
同元组一样,是一个无法修改的数据容器。修改、移除、追加指定字符等操作均无法完成,如果必须进行此类操作,只会得到一个新的字符串,旧的字符串无法修改。
字符串.index(字符串)
字符串1
替换为字符串2。
注意:不是修改字符串本身,是得到一个新的字符串。字符串.replace(字符串1, 字符串2)
字符串.split(字符串分隔符)
字符串.strip()
去除前后空格,字符串.strip(字符串)
去除前后指定字符串。字符串.count(某字符串)
统计某字符串在字符串中的出现次数,len(字符串)
统计字符串长度。# 通过下标索引取值
my_str = "xiao man yao"
value1 = my_str[3]
value2 = my_str[-1]
print(value1, value2)
# 获取元素起始下标
index = my_str.index("man")
print(index)
# 替换
new_my_str = my_str.replace("yao", "liu")
print(new_my_str)
# 分割
my_str_list = my_str.split(" ")
print(my_str_list)
print(type(my_str_list))
# 规整操作
## 去除前后空格
my_str = " xiao man yao "
new_my_str = my_str.strip()
print(new_my_str)
## 去除前后指定字符串
my_str = "axiao man yao"
new_my_str = my_str.strip("ao")
print(new_my_str)
# 统计某字符串在字符串中的出现次数
my_str = "xiao man yao"
count = my_str.count("ao")
print(count)
lenth = len(my_str)
print(lenth)
总结:
字符串[下标]
:根据下标索引取出特定位置字符;
字符串.index(字符串)
:查找给定字符的第一个匹配项的下标;
字符串.replace(字符串1, 字符串2)
:将字符串内的全部字符串1,替换为字符串2;不会修改原字符串,而是得到一个新的;
字符串.split(字符串)
:按照给定字符串,对字符串进行分隔不会修改原字符串,而是得到一个新的列表;
字符串.strip() / 字符串.strip(字符串)
:移除首尾的空格和换行符或指定字符串;
字符串.count(字符串)
:统计字符串内某字符串的出现次数;
len(字符串)
:统计字符串的字符个数。
序列:内容连续、有序,可使用下标索引的一类数据容器。列表、元组、字符串均可以视为序列。
序列支持切片,即列表、元组、字符串,均支持进行切片操作。
切片:从一个序列中,取出一个子序列。
语法:序列[起始下标:结束下标:步长]
表示从序列中,从指定位置开始,依次取出元素,到指定位置结束,得到一个新序列:
注:此操作不会影响序列本身,而是会得到一个新的序列。
# 切片
my_list = [0, 1, 2, 3, 4, 5, 6]
result = my_list[1:4] # 步长默认为1,可以省略不写
print(result)
my_tuple = (0, 1, 2, 3, 4, 5, 6)
result = my_tuple[::2] # 起始和结束不写表示从头到尾
print(result)
my_str = "012, 3, 4,5,6"
result = my_str[:]
print(result)
re_result = my_str[::-1]
print(re_result)
re_result = my_tuple[:2:-1]
print(re_result)
# 可以传递链式巴拉巴拉
my_str = "小蛮腰,是要要要,润要蛮小,冲啊"
result = my_str.split(",")[2].replace("润", "")[::-1]
print(result)
为什么需要它嘞!
俺们通过特性来看哈:
局限性:它们都支持重复元素。如果场景需要对内容做去重处理,列表、元组、字符串就更不方便了。而集合,最主要的特点就是:不支持重复元素(自带去重功能)、且内容无序。
和列表、元组、字符串等定义基本相同:
[]
()
””
{}
# 定义集合变量
my_set = {"yhz", "lr", "xmy", "yhz", "lr", "xmy", "yhz", "lr", "xmy"}
print(my_set)
print(type(my_set))
# 定义空集合
o_set = set()
print(o_set)
print(type(o_set))
o_set = {}
print(o_set)
print(type(o_set)) # 惊现字典!!!!!
首先,集合是无序的,所以集合不支持下标索引访问,且不允许重复数据存在。但是它和列表一样,允许修改。
集合.add(元素)
集合.remove(元素)
集合.pop()
集合.clear()
集合1.difference(集合2)
(得到集合 1 有而集合 2 没有的,集合 1 和集合 2 不变)集合1.difference_update(集合2)
(在集合 1内,删除和集合 2 相同的元素,集合 1 被修改,集合 2 不变)集合1.union(集合2)
# 添加元素
my_set = {"yhz", "lr"}
my_set.add("xmy")
print(my_set)
my_set.add("lr") # 添加已有元素会自动去重,相当于没添加
print(my_set)
# 移除元素
my_set.remove("xmy")
print(my_set)
# 随机取出元素
element = my_set.pop()
print(element)
print(my_set)
# 清空集合
my_set.clear()
print(my_set)
# 取两个集合的差集
set_1 = {1,2,3}
set_2 = {5,2,0}
set_3 = set_1.difference(set_2)
print(set_1)
print(set_2)
print(set_3)
# 消除两个集合的差集
set_1.difference_update(set_2)
print(set_1)
print(set_2)
# 合并集合
set_1 = {1,2,3}
set_2 = {5,2,0}
set_3 = set_1.union(set_2)
print(set_3)
# 统计集合元素数量
print(len(set_3))
注:集合不支持下标索引,不能用 while 循环,可以使用 for 循环遍历。
# 集合的遍历:集合不支持下标索引,不能用 while 循环,可以使用 for 循环遍历
my_set = {"yhz", "lr", "xmy"}
for elemnet in my_set:
print(elemnet)
总结:
集合.add(元素)
:集合内添加一个元素;
集合.remove(元素)
:移除集合内指定的元素;
集合.pop()
:从集合中随机取出一个元素;
集合.clear()
:将集合清空;
集合1.difference(集合2)
:得到一个新集合,内含2个集合的差集原有的2个集合内容不变;
集合1.difference_update(集合2)
:在集合1中,删除集合2中存在的元素集合1被修改,集合2不变;
集合1.union(集合2)
:得到1个新集合,内含2个集合的全部元素原有的2个集合内容不变;
len(集合)
:得到一个整数,记录了集合的元素数量。
字典:同样使用{}
,不过存储的元素是一个个的键值对{"key": value, "key": value, "key": value}
。
字典同集合一样,不可以使用下标索引,但可通过key
来取得对应的value
。
key
不允许重复,重复添加等同于覆盖原有数据。
字典的key
和value
可以是任意数据类型(**key
不可以是字典**),所以,字典是可以嵌套的。
# 定义字典
my_dict = {"yhz": 99, "lr": 88, "xmy": 77}
print(my_dict)
print(type(my_dict))
# 定义空字典
o_dict = {}
print(o_dict)
print(type(o_dict))
o_dict = dict()
print(o_dict)
print(type(o_dict))
# 通过key获取value
score = my_dict["lr"]
print(score)
# 嵌套字典
score_dict = {
"yhz":{
"history": 33,
"math": 99,
"art": 99
},
"lr":{
"history": 99,
"math": 66,
"art": 55
},
"xmy":{
"history": 33,
"math": 88,
"art": 77
}
}
print(score_dict)
# 从嵌套字典中获取信息
lr_math = score_dict["lr"]["math"]
print(lr_math)
key
不可以重复,所以对已存在的key
执行此操作,就是更新value
。字典[key] = value
字典[key] = value
字典.pop(key)
字典.clear()
key
。字典.keys()
# 字典的常用操作
my_dict = {"yhz": 99, "lr": 88, "xmy": 77}
# 新增元素
my_dict["run"] = 66
print(my_dict)
# 更新元素
my_dict["xmy"] = 33
print(my_dict)
# 删除元素
score = my_dict.pop("xmy")
print(score)
print(my_dict)
# 清空元素
my_dict.clear()
print(my_dict)
# 获取全部key
my_dict = {"yhz": 99, "lr": 88, "xmy": 77}
keys = my_dict.keys()
print(keys)
# 遍历字典
for key in keys:
print(key)
print(my_dict[key])
for key in my_dict:
print(key)
print(my_dict[key])
# 统计字典内元素数量
count = len(my_dict)
print(count)
总结:
字典[Key]
:获取指定Key对应的Value值;
字典[Key]=Value
:添加或更新键值对;
字典.pop(Key)
:取出Key对应的Value并在字典内删除此Key的键值对;
字典.clear()
:清空字典;
字典.keys()
:获取字典的全部Kev,可用于for循环遍历字典;
len(字典)
:计算字典内的元素数量。
# 练习:升职加薪
salary = {
"wly":{
"bm":"kjb",
"gz":3000,
"jb":1
},
"zjl":{
"bm":"scb",
"gz":50000,
"jb":2
},
"ljj":{
"bm":"scb",
"gz":7000,
"jb":3
},
"zxy":{
"bm":"kjb",
"gz":4000,
"jb":1
},
"ldh":{
"bm":"scb",
"gz":6000,
"jb":2
},
}
print(salary)
for key in salary:
if salary[key]["jb"] == 1:
salary[key]["gz"] += 1000
salary[key]["jb"] += 1
print(salary)
列表 | 元组 | 字符串 | 集合 | 字典 | |
---|---|---|---|---|---|
元素数量 | 支持多个 | 支持多个 | 支持多个 | 支持多个 | 支持多个 |
元素类型 | 任意 | 任意 | 仅字符 | 任意 | Key:Value(Key:除字典外任意类型;Value:任意类型) |
下标索引 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
重复元素 | 支持 | 支持 | 支持 | 不支持 | 不支持 |
可修改性 | 支持 | 不支持 | 不支持 | 支持 | 支持 |
数据有序 | 是 | 是 | 是 | 否 | 否 |
使用场景 | 可修改、可重复的一批数据记录场景 | 不可修改、可重复的一批数据记录场景 | 一串字符的记录场景 | 不可重复的数据记录场景 | 以 Key 检索 Value 的数据记录场景 |
数据容器尽管各自有各自的特点,但是它们也有通用的一些操作。
首先,在遍历上,5 类数据容器都支持 for 循环遍历。列表、元组、字符串支持 while 循环,集合、字典不支持(无法下标索引)。尽管遍历的形式各有不同,但是,它们都支持遍历操作。
除了遍历这个共性外,还有超多通用的功能方法。
len(容器)
:统计容器的元素个数
max(容器)
:统计容器的最大元素
min(容器)
:统计容器的最小元素
list(容器)
:将给定容器转换为列表
str(容器)
:将给定容器转换为字符串
tuple(容器)
:将给定容器转换为元组
set(容器)
:将给定容器转换为集合
注:字典转字符串会把value
保留下来,其他都会只剩key
。
排序:sorted(容器, reverse=True)
,将给定容器进行排序。注:排序结果会变成列表。
# 除遍历外,还有超多通用的功能方法
my_list = [1, 2, 3]
my_tuple = (1, 2, 3, 4)
my_str = "12345"
my_set = {1, 2, 3, 4, 5}
my_dict = {"key1": 1, "key2": 2, "key3": 3, "key4": 4, "key5": 5}
print(len(my_list))
print(len(my_tuple))
print(len(my_str))
print(len(my_set))
print(len(my_dict))
print(max(my_list))
print(max(my_tuple))
print(max(my_str))
print(max(my_set))
print(max(my_dict))
print(min(my_list))
print(min(my_tuple))
print(min(my_str))
print(min(my_set))
print(min(my_dict))
print(list(my_str))
print(type(list(my_str)))
print(str(my_list))
print(type(str(my_list)))
print(tuple(my_set))
print(type(tuple(my_set)))
print(set(my_dict))
print(type(set(my_dict)))
my_set = {4, 5, 3, 7, 0, 2}
print(sorted(my_set))
print(sorted(my_set, reverse=True))
总结:
通用for循环:遍历容器(字典是遍历key);
max()
:容器内最大元素;
min()
:容器内最小元素;
len()
:容器元素个数;
list()
:转换为列表;
tuple()
:转换为元组;
str()
:转换为字符串;
set()
:转换为集合;
sorted(序列, [reverse=True])
:排序,reverse=True
表示降序得到一个排好序的列表。