数据容器

一种可以容纳多份数据的数据类型 (容器), 容纳的每一份数据称之为 1 个元素, 每一个元素都可以是任意类型的数据, 如字符串, 数字, 布尔

列表

列表是数据容器中的一类, 是一次性可以存储多个数据(元素)的

定义:

列表名称 = [元素1, 元素2, ...] 

s = [1, 2, 3, 4]

# 空列表
变量名称 = [] 
变量名称 = list()  

特点:

  1. 可以存储不同类型的元素
  2. 元素有序 (根据添加时候的顺序) , 可以重复, 元素可以修改

可以根据索引来访问列表中的元素, 正向索引从0开始, 反向索引从 -1 开始, 如果索引是负数, 说明是反向访问

基本操作

s = [1, 2, 3, 4, 5, 6, 7]
print(s[-4])    # 4
print(type(s)) # <class 'list'> 

# 修改
s[5] = 'hello' 
print(s[5]) # hello 

# 打印列表
print(s) # [1, 2, 3, 4, 5, 'hello', 7] 
for i in s : 
    print(i, end = " ")  # 1 2 3 4 5 hello 7 
print() 

# 删除  del
del s[3] 
print(s) # [1, 2, 3, 5, 'hello', 7]

可以用print (列表名) 直接打印整个列表

列表简单操作

list = ["hello", "world", "nihao", "xinyan"]

# 获取元素的索引
index = list.index("nihao")
print(index)

# 插入元素
list.insert(1, "messory")
print(list)

# 追加单个元素
list.append("hehe")
print(list)

# 追加一批元素
# 列表.extend(数据容器), 将数据容器中的内容取出, 一次追加到列表尾部,
list1 = ["lala", "boy"]
list.extend(list1)
print(list) # ['hello', 'messory', 'world', 'nihao', 'xinyan', 'hehe', 'lala', 'boy']


# 删除元素
list = ["hello", "world", "nihao", "xinyan"]
# 1. del 列表[index]
del list[2]
print(list)
# 2. 列表.pop(index)
# 返回删除的元素
element = list.pop(1)
print(list)
print(element)

# 删除某元素在列表中的第一个匹配项
list = ['1', '2', '5', '2']
list.remove('2')
print(list) # ['1', '5', '2']

# 清空列表
list.clear()
print(list)

# 统计列表中某个元素的个数
list = ['1', '2', '5', '2']
print(list.count('2'))

# 获取容器中元素的个数 
print(len(list))

切片

切片是指对操作的数据截取其中一部分的操作, 列表, 字符串, 元组都支持切片操作

语法:

序列数据[开始索引: 结束索引: 步长]
  1. 不包含结束索引位置对应的元素 (开始索引未指定默认为 0; 结束索引未指定默认为列表长度(直到列表末尾); 步长未指定默认为 1 )
  2. 索引采用正向, 反向索引都可以
  3. 步长是选取间隔, 默认步长为 1

列表常见方法

方法作用样例
append()在列表的尾部追加元素s.append(10086)
insert()在指定索引之前,插入该元素s.insert(0, 92)
remove()移除列表中第一个匹配到的值s.remove(75)
pop()删除列表中指定索引位置的元素(如果未指定索引,默认删最后一个)s.pop(2) / s.pop()
sort()对列表进行排序(列表元素的数据类型一致,才可以进行排序)s.sort()
reverse()反转列表元素s.reverse()

sort排序要求所以的元素都是同一类型

s = [45, 56, 98, 5, 35]  
s.sort()
print(s)  #[5, 35, 45, 56, 98]
sum(列表名) 求和
len(列表名) 求元素个数
合并列表
# 合并两个列表, 并对合并后的列表去重
num1 = [12, 56, 87, 99, 87] 
num2 = [12, 99, 556, 36, 85, 87] 

print(num1) 
print(num2) 

for i in num1: 
    num2.append(i) 
print(num2)  # [12, 99, 556, 36, 85, 87, 12, 56, 87, 99, 87]  未去重

num_list = []  # 记录去重后的列表元素
 
for i in num2: 
    if i  not in num_list:  # in 判断元素是否存在于列表中, 存在返回 True, 否则返回 Flase 
        # not 取反
        num_list.append(i) 

print(num_list) # [12, 99, 556, 36, 85, 87, 56]

也可以直接用 + 将两个列表合并

num1 = [12, 56, 87, 99, 87] 
num2 = [12, 99, 556, 36, 85, 87] 

num_list = num1 + num2 

print(num_list)

in 运算符, 判断元素是否在列表中

元素 in list

判断元素是否存在于列表中, 存在返回 True, 否则返回 Flase

解包 组包

解包: 将列表这一类容器解开成一个独立的元素

组包: 将多个值合并到一个容器

num1 = [12, 56, 87, 99, 87] 
num2 = [12, 99, 556, 36, 85, 87] 

num_list = [*num1, *num2]   # 解包

print(num_list)  # [12, 56, 87, 99, 87, 12, 99, 556, 36, 85, 87]

案例: 生成1 - 20 的平方组成的列表

法一: 传统方法
法一: 
num_list = [] 
for i in range(1, 21): 
    num_list.append(i ** 2) 
print(num_list)
法二: 列表推导式

格式:

[要插入的值 for i in list] 
num_list = [] 
num_list = [i ** 2 for i in range(1, 21)]
print(num_list)

案例: 生成1 - 20 所有偶数平方的列表

列表推导式:
num_list = [] 
num_list = [i ** 2 for i in range(1, 21) if i % 2 == 0] 
print(num_list) # [4, 16, 36, 64, 100, 144, 196, 256, 324, 400]

字符串

字符串是字符的容器, 一个字符串中可以存放任意数量的字符

特点: 不可变性 (无法修改), 有序性, 可迭代性

字符串中每一个字符元素都有具有其对应的下标 (索引), 通过元素对应的索引, 就可以获取对应的元素

从前向后,(正向索引), 下标从 0 开始, 从后向前 (反向索引), 下标从 -1 开始

切片

语法: 序列对象[开始索引: 结束索引: 步长]

s = "hello world" 

print(s[4]) 
print(s[1: 6: 2]) 

不会取到结束索引对应的元素

如果是从 0 开始或者步长为 1 , 可以省略开始索引和步长

s = "hello world" 

print(s[: 5: ]) 
print(s[1: 6: ])

步长为负数表示从后往前截取

s = "hello world" 
print(s[6: 0: -1]) # w olle

反向截取的时候要注索引和结束索引也要从后往前

切片不会改变原序列

字符串是不可修改的

常用方法

方法作用样例
find()在字符串中查找子串,返回第一次出现的索引位置,找不到返回 - 1s.find(‘Python’)
count()统计子串在字符串中出现的次数s.count(‘H’)
upper()将字符串中的所有字母转换为大写s.upper()
lower()将字符串中的所有字母转换为小写s.lower()
split()将字符串按指定分隔符分割成列表s.split(’ ')
strip()去除字符串两端的空白字符或指定字符s.strip() / s.strip(‘*’)
replace()将字符串中的指定子串替换为新的子串s.replace(‘H’, ‘C’)
startswith()检查字符串是否以指定子串开头,返回布尔值s.startswith(‘P’)

字符串的替换

语法:字符串.replace (字符串 1,字符串 2)

功能:将字符串内的全部:字符串 1,替换为字符串 2

注意:不是修改字符串本身,而是得到了一个新字符串 

这里是将字符串中所有的 字符串1 子串都替换为 字符串2

元组(tuple)

列表特点: 元素可重复, 有序, 可以修改

如果需要记录一些信息, 而且不能修改, 只能查询, 就可以考虑使用元组:

元组一旦定义完成, 不可修改

介绍

元组是不可变的序列, 类似于列表, 但创建后不能修改

特点

  1. 可以存储不同类型的元素
  2. 元素可以重复, 有序, 不可以修改 (支持索引访问, 切片)

定义

元组名称 = (元素1, 元素2, ...) 

# 定义空元组
元组名称 = () 
元组名称 = tuple()

方法

  1. count() 统计某元素在元组中出现的次数
  2. index() 查找某个元素在元组中索引位置 (第一次出现的位置), 否则报错
  3. len(元组), 统计元组中的元素个数
t1 = (12, 23, 54, 54, 5)
print(type(t1)) # <class 'tuple'>
print(t1[-1]) # 5

可以正向访问, 也可以反向访问

**如果要定义单个元素的元组, 单个元素之后需要加上逗号 , **

t = (100) 
print(type(t))  # <class 'int'>
t1 = (100, ) 
print(type(t1)) # <class 'tuple'>

组包与解包

  • 组包 (Packing): 将多个值合并到一个容器 (元组, 列表) 中
  • 解包 (Unpacking): 将容器 (元组, 列表) 解开成独立的元素, 分别赋值给多个变量
# 定义元组, 组包
t1 = (5, 7, 9, 1) 
t2 = 5, 7, 9, 1


# 基础解包
a, b, c, d = t1 


# ( * ) 扩展解包
x, *y, z = t2   # x 为 5, y 为 [7, 9] z 为 1
s, *o = t2      # s 为 5, o 为 [7, 9, 1]
*o, e = t2      # o 为 [5, 7, 9], e 为 1

**在元组解包时, * 表示收集剩余元素, 允许我们处理不确定数量的元素 (生成列表, 以便可以进行进一步的处理) **

通过组包和解包交换两个变量的值

a = 10 
b = 20 
a, b = b, a  
print(a) # 20
print(b) # 10

案例

# 保存学生信息
students = (
    ("S001", "王林", 85, 92, 78),
    ("S002", "李慕婉", 92, 88, 95),
    ("S003", "十三", 78, 85, 82),
    ("S004", "曾牛", 88, 79, 91),
    ("S005", "周软", 95, 96, 89),
    ("S006", "王卓", 76, 82, 77),
    ("S007", "红蝶", 89, 91, 94),
    ("S008", "徐立国", 75, 69, 82),
    ("S009", "许木", 86, 89, 98),
    ("S010", "通天", 66, 59, 72)
) 

print("学号\t 姓名 \t 语文 \t 数学 \t 英语 \t 总分 \t 平均分") 

## 方式一
# # 计算每个学生的总分, 各科平均分, 然后一并输出
# for s in students: 
#     total = s[2] + s[3] + s[4]  
#     ava = total / 3 
#     print(f"{s[0]} \t{s[1]}\t {s[2]} \t {s[3]} \t {s[4]} \t {total} \t {ava: .1f}") 


## 方式二: 元组解包 
for id, name, chinese, math, english in students: 
    total = chinese + math + english 
    avg = total / 3 
    print(f"{id} \t {name}\t {chinese} \t {math} \t {english} \t {total} \t {avg: .1f}")


    
# 统计各学科的最低分, 最高分, 平均分 
# 获取到各科的成绩列表 
chinese_score = [s[2] for s in students] 
math_score = [s[3] for s in students] 
english_score = [s[4] for s in students] 

# 统计各科成绩的最高分, 最低分, 平均分
print(f"chinese min_score is {min(chinese_score)}, max_score is {max(chinese_score)}, avarage is {sum(chinese_score) / len(chinese_score)}") 
print(f"math min_score is {min(math_score)}, max_score is {max(math_score)}, avarage is {sum(math_score) / len(math_score)}") 
print(f"english min_score is {min(english_score)}, max_score is {max(english_score)}, avarage is {sum(english_score) / len(english_score)}") 


方法一: 
# # 查找成绩优秀 (平均分大于 90) 的学生 
# for s in students: 
#     total = s[2] + s[3] + s[4] 
#     avg = total / 3 
#     if avg > 90: 
#         print(f"学号: {s[0]}, 姓名: {s[1]}, 平均分: {avg: .1f}")


方法二: 
# 元组解包
for id, name, chinese, math, english in students:  
    total = chinese + math + english 
    avg = total / 3 
    if avg > 90: 
        print(f"学号: {id}, 总分: {total}, 平均分: {avg: .1f}")

集合 (set)

集合是一种无序的, 不可重复, 可修改的数据容器

空集合的定义不可以使用{}, {}表示的是空字典, 由于集合是无序的, 因此是不支持下标索引访问的

s1 = {5, 3, 0, 6, 6, 3, 8, 4} 
print(s1) # {0, 3, 4, 5, 6, 8}
print(type(s1)) # <class 'set'>

集合的定义

定义1: 集合名 = {元素1, 元素2, 元素3...}

定义2: 集合名 = set()

空集合的定义不可以使用{}, {}表示的是空字典

集合基本操作

操作含义样例
add(…)添加元素到集合中s1.add(‘t’)
remove(…)移除集合中的指定元素(指定元素不存在将报错)s1.remove(‘t’)
pop()随机删除集合中的元素并返回e = s1.pop()
clear()清空集合s1.clear()
difference()求取两个集合的差集(包含在第一个集合但不包含在第二个集合的元素)s1.difference(s2)
union()求取两个集合的并集s1.union(s2)
intersection()求取两个集合的交集s1.intersection(s2)
# 消除两个集合的差集 
语法: s1.difference_updata(s2) 
功能: 对比集合一和集合二, 在集合一内,消除与集合二相同的yuan

集合推导式

快速构建集合

语法

{要往集合中添加的元素 for s in set1 if 条件}

案例练习

# 选修足球学生名单
football_set = {"王林", "曾牛", "徐立国", "通天", "天运子", "韩立", "厉飞雨", "乌丑", "紫灵"}

# 选修篮球学生名单
basketball_set = {"张铁", "墨居仁", "王林", "姜老道", "曾牛", "王蝉", "韩立", "天运子", "李化元", "厉飞雨", "云露"}

# 选修法语学生名单
french_set = {"许木", "王卓", "十三", "虎咆", "姜老道", "天运子", "红蝶", "厉飞雨", "韩立", "曾牛"}

# 选修艺术学生名单
art_set = {"通天", "天运子", "韩立", "虎咆", "姜老道", "紫灵"}

# 1、找出同时选修了 法语 和 艺术 的学生 
## 方式一: 交集
fa_set = french_set.intersection(art_set) 
print("同时选修了法语和艺术的学生: ", fa_set) 

## 方式二   & 
fa_set = french_set & art_set
print("同时选修了法语和艺术的学生: ", fa_set)  


# 2、找出同时选修了所有四门课程的学生
all_set = football_set & basketball_set & french_set & art_set 
print("同时选修了所有课程的学生: ", all_set)  

# 3、找出选修了足球,但是没有选修篮球的学生 
# 方法一 
fb_set = football_set.difference(basketball_set) 
print("选修了足球,但是没有选修篮球的学生: ", fb_set)

## 方法二:  - 运算符
fb_set = football_set - basketball_set 
print("选修了足球,但是没有选修篮球的学生: ", fb_set)

## 集合推导式 -- > 快速构建一个集合 
print("选修了足球,但是没有选修篮球的学生: ", {s for s in football_set if  s not in basketball_set}) 


# 4、统计每一个学生选修的课程数量 


# 获取所有学生 

# 并集 union 或 | 运算符
all_set = football_set.union(basketball_set).union(french_set).union(art_set) 
print(all_set)  


# 统计学生选修课程的数量
all_list = [*football_set, *basketball_set, * french_set, art_set] 
for s in all_set:
    print(f"{s} 选修了 {all_list.count(s)} 门课程")

字典

python 中字典(dict), 里面存储的是键值对(key: value) 类型的数据, 可以根据键(key) 找到对应的值 (vlaue)

特点;

键值对 (key: value) 存储, 键(key) 不能重复, 不可修改

定义

字典名称 = {key: value, key: value, key: value ...} 

# 空字典 
字典名称 = {} 
字典名称 = dict() 

字典(dict) 中的value 可以是任意类型的数据, 而 key 不能为可变类型, (如不能为 list, set, dict)

defaultdict

普通字典访问不存在的键会直接报错 KeyError,而 defaultdict给不存在的键自动生成一个默认值

基本操作

类型操作语法含义样例
添加字典名称 [key] = value往指定字典中添加 key-value 键值对dict1 [“涛哥”] = 688
删除字典名称.pop (key)删除指定 key,返回对应 valuescore = dict1.pop (“涛哥”)
删除del 字典名称 [key]删除指定的键值对del dict1 [“涛哥”]
修改字典名称 [key] = value修改指定 key 对应的值dict1 [“小智”] = 658
查询字典名称 [key]根据 key 获取 value(key 不存在会报错)dict1 [“涛哥”]
查询字典名称.get (key)根据 key 获取 value(key 不存在返回 None)dict1.get (“涛哥”)
查询字典名称.keys ()获取所有的 keydict1.keys()
查询字典名称.values ()获取所有的 valuedict1.values()
查询字典名称.items ()获取所有的 key-value 键值对dict1.items()

数据容器总结与对比

特性字符串(str)列表(list)元组(tuple)集合(set)字典(dict)
有序性有序有序有序无序有序 (3.7+)
重复元素允许允许允许不允许key 不允许
可变性不可变可变不可变可变可变
索引访问支持支持支持不支持不支持
切片操作支持支持支持不支持不支持
使用场景文本处理有序可重复数据集合固定数据记录去重数据集合键值对

更多推荐