数据容器概述
能够存储多个数据(元素)的数据类型,即"容纳"多份数据的容器
在编程的过程中,我们需要对批量的数据进行统一的管理,这时候不能再用单一变量去一个个存储,不仅麻烦且不易维护。数据容器就是为了解决这个问题而存在的——它可以把多个数据组织在一起,方便统一操作。
Python 中常用的数据容器分为以下 5 类:
容器
类型标识
特点
可变性
元素是否有序
元素是否可重复
列表
list
最通用的序列容器
可变
有序
可重复
元组
tuple
不可修改的序列容器
不可变
有序
可重复
字符串
str
字符组成的序列容器
不可变
有序
可重复
集合
set
去重、数学运算
可变
无序
不可重复
字典
dict
键值对映射容器
可变
有序(Python 3.7+)
键不可重复
1 2 3 4 5 6 7 8 9 10 11 12 list_data = [1 , 2 , 3 ] tuple_data = (1 , 2 , 3 ) str_data = "hello" set_data = {1 , 2 , 3 } dict_data = {"a" : 1 , "b" : 2 } print (type (list_data)) print (type (tuple_data)) print (type (str_data)) print (type (set_data)) print (type (dict_data))
列表(List)
列表是 Python 中最常用的数据容器,可以存储任意类型、任意数量的元素,支持增删改查等操作
列表是一个有序 、可变 的序列容器,使用方括号 [] 定义,元素之间用逗号分隔。
列表的定义
1 2 3 4 5 6 7 8 9 10 11 12 empty_list = [] nums = [1 , 2 , 3 , 4 , 5 ] mixed = [1 , "hello" , 3.14 , True ] nested = [[1 , 2 ], [3 , 4 ], [5 , 6 ]] chars = list ("abc" ) print (chars) range_list = list (range (1 , 6 )) print (range_list)
列表的下标索引
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 """ 列表通过下标(索引)访问元素: - 正向索引:从左往右,从 0 开始计数 - 反向索引:从右往左,从 -1 开始计数 """ fruits = ["苹果" , "香蕉" , "橘子" , "葡萄" , "西瓜" ] print (fruits[0 ]) print (fruits[2 ]) print (fruits[-1 ]) print (fruits[-3 ]) matrix = [[1 , 2 , 3 ], [4 , 5 , 6 ], [7 , 8 , 9 ]] print (matrix[1 ][2 ])
列表的常用方法 — 查询与遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 fruits = ["苹果" , "香蕉" , "橘子" ] print (len (fruits)) for fruit in fruits: print (fruit) for index, fruit in enumerate (fruits): print (f"{index} : {fruit} " ) print (fruits.index("香蕉" )) nums = [1 , 2 , 3 , 2 , 1 , 2 ] print (nums.count(2 ))
列表的常用方法 — 增加元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 nums = [1 , 2 , 3 ] nums.append(4 ) print (nums) nums.insert(0 , 0 ) print (nums) nums.extend([5 , 6 ]) print (nums) a = [1 , 2 ] b = [3 , 4 ] c = a + b print (c)
列表的常用方法 — 删除元素
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 nums = [10 , 20 , 30 , 40 , 50 ] last = nums.pop() print (last) print (nums) second = nums.pop(1 ) print (second) print (nums) nums = [1 , 2 , 3 , 2 , 4 ] nums.remove(2 ) print (nums) nums = [10 , 20 , 30 ] del nums[1 ]print (nums) nums.clear() print (nums)
列表的常用方法 — 修改与排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 fruits = ["苹果" , "香蕉" , "橘子" ] fruits[1 ] = "草莓" print (fruits) nums = [1 , 2 , 3 , 4 , 5 ] nums.reverse() print (nums) nums = [3 , 1 , 4 , 1 , 5 , 9 ] nums.sort() print (nums) nums.sort(reverse=True ) print (nums) nums = [3 , 1 , 4 ] sorted_nums = sorted (nums) print (sorted_nums) print (nums)
列表推导式
一种简洁地创建列表的方式,可以在一行代码内完成循环+条件判断
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 squares = [x ** 2 for x in range (1 , 11 )] print (squares) evens = [x for x in range (1 , 21 ) if x % 2 == 0 ] print (evens) pairs = [(x, y) for x in range (1 , 3 ) for y in "ab" ] print (pairs) grades = [85 , 92 , 78 , 60 , 45 , 95 ] result = ["及格" if g >= 60 else "不及格" for g in grades] print (result)
元组(Tuple)
元组是"不可变"的序列容器,一旦定义,其元素不可被修改、添加或删除
元组使用圆括号 () 定义,元素之间用逗号分隔。由于不可修改,元组比列表更安全、占用内存更小,适合存储不需要改变的数据。
元组的定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 empty_tuple = () single = (1 ,) nums = (1 , 2 , 3 ) without_parens = 1 , 2 , 3 mixed = (1 , "hello" , 3.14 ) not_tuple = (1 ) print (type (not_tuple)) print (type ((1 ,))) chars = tuple ("abc" ) print (chars) list_to_tuple = tuple ([1 , 2 , 3 ]) print (list_to_tuple)
元组的基本操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 info = ("小明" , 18 , "北京" , 95.5 ) print (info[0 ]) print (info[-1 ]) print (len (info)) nums = (1 , 2 , 3 , 2 , 1 , 2 ) print (nums.count(2 )) print (nums.index(3 )) for item in info: print (item) name, age, city, score = info print (name, age, city, score)
元组的不可变性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 t = (1 , 2 , 3 ) t = (4 , 5 , 6 ) print (t) t = (1 , [2 , 3 ], 4 ) t[1 ][0 ] = 99 print (t)
字符串(String)
字符串是字符组成的不可变序列容器,支持索引、切片等序列操作
字符串在前面的笔记中已经接触过。作为数据容器来看,字符串本质上是字符的序列 ,因此也支持下标索引和切片操作。
字符串作为序列容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 text = "Python" print (text[0 ]) print (text[-1 ]) print (len (text)) for ch in text: print (ch, end=" " ) print ()print ("th" in text) print ("xy" in text)
字符串的常用方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 s = " Hello Python World " print (s.upper()) print (s.lower()) print (s.title()) print (s.strip()) print (s.lstrip()) print (s.rstrip()) print (s.find("Python" )) print (s.replace("World" , "Python" )) words = "苹果,香蕉,橘子" fruits_list = words.split("," ) print (fruits_list) joined = "-" .join(fruits_list) print (joined) print ("abc" .isalpha()) print ("123" .isdigit()) print ("abc123" .isalnum()) name, age = "小明" , 18 print ("我叫{},今年{}岁" .format (name, age)) print (f"我叫{name} ,今年{age} 岁" )
序列的切片操作 重点
切片(Slice)可以从序列容器中一次性取出多个元素,生成一个新的序列对象
列表、元组、字符串都是序列类型 ,它们共同支持切片操作。切片是 Python 序列容器最强大的特性之一。
切片的基本语法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 """ 序列[起始位置 : 结束位置 : 步长] - 起始位置:包含,默认为 0(可省略) - 结束位置:不包含,默认为序列长度(可省略) - 步长:每次跨越的元素个数,默认为 1(可省略) - 切片不会修改原序列,而是生成一个新的序列对象 """ nums = [0 , 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 ] print (nums[2 :7 ]) print (nums[:5 ]) print (nums[5 :]) print (nums[:]) print (nums[::2 ]) print (nums[::-1 ])
三种序列的切片对比
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 lst = [1 , 2 , 3 , 4 , 5 ] print (lst[1 :4 ]) print (lst[::-1 ]) tup = (1 , 2 , 3 , 4 , 5 ) print (tup[1 :4 ]) print (tup[::2 ]) text = "Hello World" print (text[0 :5 ]) print (text[::-1 ]) print (text[::2 ])
切片的实用技巧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 nums = [1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 ] first_three = nums[:3 ] print (first_three) last_three = nums[-3 :] print (last_three) reversed_nums = nums[::-1 ] print (reversed_nums) nums[2 :5 ] = [] print (nums) nums[2 :2 ] = [3 , 4 , 5 ] print (nums)
集合(Set)
集合是一种无序、不可重复的数据容器,支持并集、交集、差集等数学中的集合运算
集合使用花括号 {} 定义(空集合必须用 set()),元素必须是不可变类型,且自动去重。
集合的定义与基本操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 empty_set = set () nums = {1 , 2 , 3 , 4 , 5 } mixed = {1 , "hello" , 3.14 , (1 , 2 )} s = {1 , 1 , 2 , 2 , 3 , 3 } print (s) print (2 in s) print (10 in s)
集合的常用方法 — 增删改
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 s = {1 , 2 , 3 } s.add(4 ) print (s) s.add(2 ) print (s) s.update([5 , 6 , 7 ]) print (s) s.remove(7 ) print (s) s.discard(10 ) popped = s.pop() print (popped) s.clear() print (s)
集合运算
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 a = {1 , 2 , 3 , 4 } b = {3 , 4 , 5 , 6 } print (a | b) print (a.union(b)) print (a & b) print (a.intersection(b)) print (a - b) print (a.difference(b)) print (a ^ b) print (a.symmetric_difference(b)) print ({1 , 2 } <= a) print (a >= {1 , 2 })
集合的应用场景
1 2 3 4 5 6 7 8 9 10 11 12 13 nums = [1 , 2 , 2 , 3 , 3 , 3 , 4 ] unique = list (set (nums)) print (unique) large_data = set (range (1000000 )) print (999999 in large_data) words = ["苹果" , "香蕉" , "苹果" , "橘子" , "香蕉" ] unique_count = len (set (words)) print (f"不重复的有 {unique_count} 种" )
字典(Dictionary)
字典是一种以键值对(Key-Value Pair)存储数据的映射型容器,通过键(Key)来快速访问值(Value)
字典使用花括号 {} 定义,每个元素由 key: value 组成。键必须是不可变类型(通常为字符串或数字),值可以是任意类型。Python 3.7+ 字典默认有序(按插入顺序)。
字典的定义
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 empty_dict = {} empty_dict2 = dict () student = { "name" : "小明" , "age" : 18 , "score" : 95 } person = dict (name="小红" , age=20 , city="北京" ) print (person) pairs = [("a" , 1 ), ("b" , 2 ), ("c" , 3 )] d = dict (pairs) print (d)
字典的访问与遍历
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 student = {"name" : "小明" , "age" : 18 , "score" : 95 } print (student["name" ]) print (student.get("age" )) print (student.get("level" , "未知" )) for key in student.keys(): print (key, end=" " ) print ()for value in student.values(): print (value, end=" " ) print ()for key, value in student.items(): print (f"{key} : {value} " )
字典的增删改操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 student = {"name" : "小明" , "age" : 18 } student["score" ] = 95 print (student) student["age" ] = 19 print (student) student.update({"age" : 20 , "city" : "北京" }) print (student) city = student.pop("city" ) print (city) print (student) item = student.popitem() print (item) del student["age" ]print (student) student.clear() print (student)
字典推导式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 squares = {x: x ** 2 for x in range (1 , 6 )} print (squares) even_squares = {x: x ** 2 for x in range (1 , 11 ) if x % 2 == 0 } print (even_squares) original = {"a" : 1 , "b" : 2 , "c" : 3 } reversed_dict = {v: k for k, v in original.items()} print (reversed_dict)
映射类型 了解即可
映射(Mapping)是一种通过键直接查找对应值的数据结构,字典是 Python 唯一的原生映射类型
字典之所以被称为"映射"类型,是因为它实现了键 → 值 的对应关系,就像现实中的字典:通过一个"字"(键)来查找它的"释义"(值)。
映射的核心特性
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 """ 映射类型的三个核心特性: 1. 键唯一:同一个键不能出现多次 2. 通过键快速查找值:类似用查字典,不需要遍历 3. 键必须是不可变类型:因为内部使用哈希表实现 """ d = {"a" : 1 , "b" : 2 , "a" : 3 } print (d) """ 为什么字典的键必须是不可变类型? 字典的内部实现基于"哈希表"(Hash Table)。哈希表的工作原理是: 1. 通过 hash() 函数计算键的哈希值(一个固定长度的整数) 2. 根据哈希值快速定位到存储位置 3. 如果键是可变的,其哈希值也会变化,导致之前存储的数据"丢失" 所以要求键必须是"可哈希的"(hashable),即该对象拥有一个在其生命周期 内永不改变的哈希值。只有不可变类型满足这个条件。 """ print (hash ("hello" )) print (hash ((1 , 2 , 3 ))) print (hash (42 )) works = { 1 : "整数可以" , "s" : "字符串可以" , (1 , 2 ): "元组可以" , 3.14 : "浮点数可以" , True : "布尔值可以" , None : "None 可以" , } data = {f"key_{i} " : i for i in range (1000000 )} print ("key_999999" in data)
字典的常用技巧
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 words = ["苹果" , "香蕉" , "苹果" , "橘子" , "香蕉" , "苹果" ] counter = {} for word in words: counter[word] = counter.get(word, 0 ) + 1 print (counter)users = { 101 : {"name" : "小明" , "role" : "admin" , "login_count" : 15 }, 102 : {"name" : "小红" , "role" : "user" , "login_count" : 8 }, 103 : {"name" : "小刚" , "role" : "user" , "login_count" : 23 }, } active_users = [] for uid, info in users.items(): if info["login_count" ] > 10 : active_users.append(info["name" ]) print (f"活跃用户:{active_users} " ) user = {"name" : "小明" , "profile" : {"age" : 18 }} print (user.get("profile" , {}).get("age" , "未知" )) print (user.get("profile" , {}).get("score" , "未知" ))
数据容器对比总结
每种数据容器都有各自的特点和适用场景,根据需求选择合适的容器
五大容器全面对比
特性
列表
元组
字符串
集合
字典
定义符号
[]
()
"" / ''
{}
{k: v}
类型名
list
tuple
str
set
dict
有序否
有序
有序
有序
无序
有序(3.7+)
可修改
是
否
否
是
是
可重复
是
是
是
否
键否/值是
下标索引
支持
支持
支持
不支持
不支持(按键取)
切片
支持
支持
支持
不支持
不支持
成员判断
in
in
in
in
in(查键)
通用操作(所有容器都支持)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 lst = [1 , 2 , 3 ] tup = (1 , 2 , 3 ) s = "hello" st = {1 , 2 , 3 } d = {"a" : 1 , "b" : 2 } print (len (lst), len (tup), len (s), len (st), len (d))print (1 in lst) print ("h" in s) print (1 in st) print ("a" in d) nums = [3 , 1 , 4 , 1 , 5 ] print (max (nums)) print (min (nums)) print (sorted (nums)) print (list ((1 , 2 , 3 ))) print (tuple ([1 , 2 , 3 ])) print (set ([1 , 2 , 2 , 3 ])) print (list ({"a" : 1 , "b" : 2 }))
如何选择合适的容器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 """ 根据需求选择最合适的容器: ├── 需要按位置存储,可能修改内容? │ └── 是 → 使用 列表(list) │ 否 → 使用 元组(tuple) │ ├── 处理文本(字符序列)? │ └── 是 → 使用 字符串(str) │ ├── 需要去重、做数学集合运算? │ └── 是 → 使用 集合(set) │ └── 需要通过键快速查找值? └── 是 → 使用 字典(dict) """ cart = ["苹果" , "香蕉" , "橘子" ] cart.append("葡萄" ) point = (120.1 , 30.2 ) tags = {"Python" , "编程" , "教程" } tags.add("Python" ) students = {"小明" : 95 , "小红" : 88 , "小刚" : 76 } print (students["小明" ])
综合练习
将所学知识融会贯通,通过实际案例巩固数据容器的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 """ 使用多种数据容器综合处理学生成绩数据 """ scores = [85 , 92 , 78 , 60 , 95 , 45 , 88 , 73 , 58 , 91 ] total = sum (scores) count = len (scores) avg = total / count print (f"总人数:{count} ,平均分:{avg:.1 f} " )unique_scores = set (scores) print (f"不同分数的种类:{len (unique_scores)} " )grade_count = {"优秀" : 0 , "良好" : 0 , "中等" : 0 , "及格" : 0 , "不及格" : 0 } for score in scores: if score >= 90 : grade_count["优秀" ] += 1 elif score >= 80 : grade_count["良好" ] += 1 elif score >= 70 : grade_count["中等" ] += 1 elif score >= 60 : grade_count["及格" ] += 1 else : grade_count["不及格" ] += 1 for grade, num in grade_count.items(): print (f" {grade} :{num} 人" ) sorted_scores = sorted (scores, reverse=True ) top3 = tuple (sorted_scores[:3 ]) print (f"前三名成绩:{top3} " )passed_count = len ([s for s in scores if s >= 60 ]) print (f"及格率:{passed_count / count * 100 :.1 f} %" )
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 """ 统计一段文本中每个词的词频,按频率从高到低排序 """ text = """ Python is an easy to learn powerful programming language It has efficient high-level data structures and a simple but effective approach to object-oriented programming Python is an interpreted language """ words = text.lower().split() print (f"总词数:{len (words)} " )word_count = {} for word in words: word_count[word] = word_count.get(word, 0 ) + 1 stopwords = {"is" , "an" , "to" , "a" , "and" , "it" , "but" , "the" } for sw in stopwords: word_count.pop(sw, None ) sorted_words = sorted (word_count.items(), key=lambda x: x[1 ], reverse=True ) print ("\n词频统计 TOP 5:" )for word, count in sorted_words[:5 ]: print (f" {word} :出现 {count} 次" )
数据容器是 Python 的核心基础。列表灵活多变、元组安全高效、字符串处理文本、集合适配去重与数学运算、字典实现快速键值映射。理解每种容器的特性和适用场景,才能在实际编程中做出最优选择。
Python Study Note 系列文章
Python Study Note Python 函数使用(四) Python 判断语句(二) Python 基础语法(一) Python 异常处理(七) Python 循环语句(三) Python 数据容器(五) Python 文件基础操作(六) Python 模块与包(八) Python 类型注解(十) Python 面向对象(九)重点 Python 高阶技巧(十一)