大家好,我是大华!
最近在系统地学习 Python。一方面是因为 AI 发展得太快了,Python 几乎成了绕不开的一门语言;另一方面,也想借这个机会,把自己的学习过程完整记录下来。
今天主要记录的是 python 的核心数据结构
一、列表(List)
列表可以理解为加强版的动态数组,和数组不同的是,同一个列表可以存储不同的数据类型。
1.1 创建列表
# 创建空列表empty_list = []empty_list2 = list()# 创建有元素的列表fruits = ['apple', 'banana', 'orange', 'grape']numbers = [1, 2, 3, 4, 5]mixed = [1, 'hello', 3.14, True]print(f"水果列表: {fruits}")print(f"数字列表: {numbers}")print(f"混合列表:{mixed}")
输出结果:
水果列表: ['apple', 'banana', 'orange', 'grape']数字列表: [1, 2, 3, 4, 5]混合了吧:[1, 'hello', 3.14, True]
1.2 列表基本操作
# 访问元素(索引从0开始)fruits = ['apple', 'banana', 'orange', 'grape']print(fruits[0]) # 'apple'print(fruits[-1]) # 'grape'(最后一个元素)# 修改元素fruits[1] = 'mango'print(fruits) # ['apple', 'mango', 'orange', 'grape']# 添加元素fruits.append('peach') # 末尾添加fruits.insert(2, 'watermelon') # 指定位置插入print(fruits)
输出结果:
applegrape['apple', 'mango', 'orange', 'grape']['apple', 'mango', 'watermelon', 'orange', 'grape', 'peach']
1.3 列表切片
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 基本切片print(numbers[2:5]) # [2, 3, 4]print(numbers[:4]) # [0, 1, 2, 3]print(numbers[6:]) # [6, 7, 8, 9]print(numbers[::2]) # [0, 2, 4, 6, 8](步长为2)# 复制列表numbers_copy = numbers[:]
1.4 列表常用方法
fruits = ['apple', 'banana', 'orange','grape','banana', 'grape']# 删除元素fruits.remove('banana') # 删除第一个匹配项print(f"删除后的水果列表: {fruits}")popped = fruits.pop(3) # 删除并返回指定位置元素print(f"弹出的元素: {popped}")# 查找元素index = fruits.index('orange') # 查找索引count = fruits.count('grape') # 统计出现次数print(f"索引: {index}")print(f"出现次数: {count}")# 排序numbers = [3, 1, 4, 1, 5, 9, 2]numbers.sort() # 升序排序print(f"排序后的列表: {numbers}")numbers.sort(reverse=True) # 降序排序print(f"降序排序后的列表: {numbers}")
输出结果:
删除后的水果列表: ['apple', 'orange', 'grape', 'banana', 'grape']弹出的元素: banana索引: 1出现次数: 2排序后的列表: [1, 1, 2, 3, 4, 5, 9]降序排序后的列表: [9, 5, 4, 3, 2, 1, 1]平方列表: [1, 4, 9, 16, 25]偶数列表: [0, 2, 4, 6, 8]
二、元组(Tuple)
元组是一个不可变的列表。
2.1 创建元组
# 创建元组(使用圆括号)empty_tuple = ()single_tuple = ('hello',) # 单个元素需要加逗号coordinates = (10, 20)colors = ('red', 'green', 'blue')print(f"空元组: {empty_tuple}")print(f"单元素元组: {single_tuple}")print(f"坐标元组: {coordinates}")print(f"颜色元组: {colors}")# 也可以省略括号point = 10, 20print(f"点的坐标: {point}")# 元组是不可变的# colors[0] = 'yellow' # 这会报错!
输出结果:
空元组: ()单元素元组: ('hello',)坐标元组: (10, 20)颜色元组: ('red', 'green', 'blue')点的坐标: (10, 20)
2.2 元组操作
# 解包元组dimensions = (1920, 1080)width, height = dimensionsprint(f"宽度: {width}, 高度: {height}")# 交换两个变量的值(Python技巧)a, b = 5, 10a, b = b, aprint(f"a={a}, b={b}") # a=10, b=5# 元组方法colors = ('red', 'green', 'blue', 'green')print(colors.index('blue')) # 2print(colors.count('green')) # 2
输出结果:
宽度: 1920, 高度: 1080a=10, b=522
三、元组和列表的区别?
列表是可变的,而元组不可以。
# 元组:配置信息 - 不应该被修改DATABASE_CONFIG = ("localhost", 3306, "my_database")API_KEYS = ("key123", "secret456")# 尝试修改会报错!# DATABASE_CONFIG[0] = "127.0.0.1" # TypeError!# 列表:用列表就可能被意外修改bad_config = ["localhost", 3306] # 可能被误改bad_config[0] = "hacker.com" # 不会报错,但有风险
3.1 元组和列表区别对比
| 特性 | 列表 (List) | 元组 (Tuple) | 影响 |
|---|
| 可变 | 不可变 | 核心区别 |
| | | |
| | 较小 | |
| | 更快 | |
| | 可哈希 | |
| | 天生安全 | |
| 丰富 | | |
| | 更常用 | |
| | 稍快 | |
3.2 什么时候用元组?
1. 函数返回多个值(后面的文章再写函数)
def get_user_info(): return ("张三", 25, "北京") # 姓名, 年龄, 地址name, age, address = get_user_info() # 直接解包
2. 字典键或集合元素(本文的下面有写字典的内容)
# 坐标作为字典键locations = { (40.7128, -74.0060): "纽约", (51.5074, -0.1278): "伦敦"}# 元组放入集合去重unique_pairs = {("a", 1), ("b", 2), ("a", 1)}
3. 配置信息、常量
DATABASE = ("localhost", 3306, "my_db")COLORS = ("红", "绿", "蓝", "黄")API_KEYS = ("key123", "secret456")
4. 坐标、尺寸等固定结构
point = (10, 20) # 二维点size = (1920, 1080) # 屏幕分辨率 rgb = (255, 0, 0) # 颜色值date = (2024, 1, 20) # 年月日
5. 保证数据不被误改
# 重要数据用元组保护STUDENT_TEMPLATE = ("姓名", "学号", "成绩") # 不会被修改
6. 性能敏感场景
# 大量只读数据用元组更快CONSTANTS = (1.618, 3.14159, 2.71828) # 黄金分割, π, e# 测试性能import timeitlist_time = timeit.timeit('x = [1, 2, 3, 4, 5]', number=1000000)tuple_time = timeit.timeit('x = (1, 2, 3, 4, 5)', number=1000000)print(f"列表: {list_time:.3f}s, 元组: {tuple_time:.3f}s") # 元组更快
测试结果:
列表: 0.027s, 元组: 0.008s
7. 多线程共享数据
import threading# 元组线程安全SHARED_CONFIG = ("server", 8080) # 多个线程可安全读取# 列表需要锁保护shared_list = [] # 需要 threading.Lock()
3.3 什么时候用列表?
1. 需要频繁增删数据
# 购物车cart = ["苹果", "牛奶", "面包"]cart.append("鸡蛋") # 添加cart.remove("牛奶") # 删除cart[0] = "香蕉" # 修改
2. 需要排序、反转、搜索
scores = [85, 92, 78, 95, 88]scores.sort() # 排序scores.reverse() # 反转idx = scores.index(92) # 查找索引scores.count(85) # 计数
3. 栈或队列结构
# 栈(后进先出)stack = []stack.append("任务1") # 入栈stack.append("任务2")task = stack.pop() # 出栈# 队列(先进先出)queue = []queue.append("任务1") # 入队queue.append("任务2")task = queue.pop(0) # 出队(慢,建议用deque)
4. 需要切片修改
data = [1, 2, 3, 4, 5, 6, 7, 8, 9]data[2:5] = [30, 40, 50] # 替换切片data[::2] = [0] * 5 # 替换步长为2的位置del data[3:6] # 删除切片
6. 数据需要清空、复制、扩展
items = ["a", "b", "c"]items_copy = items.copy() # 浅拷贝items.clear() # 清空items.extend(["d", "e", "f"]) # 扩展
7. 需要复杂的数据结构
# 二维矩阵matrix = [ [1, 2, 3], [4, 5, 6], [7, 8, 9]]matrix[0][1] = 20 # 修改元素matrix.append([10, 11, 12]) # 添加新行
四、字典(Dictionary)- 键值对存储
4.1 创建字典
# 创建字典student = {}student2 = dict()# 带初始值的字典student = { 'name': '张三', 'age': 20, 'major': '计算机科学', 'grades': {'math': 90, 'english': 85}}# 访问值print(student['name']) # 直接访问print(student.get('age')) # 使用get方法print(student.get('phone', '未提供')) # 提供默认值
输出结果:
张三20未提供
4.2 字典操作
# 添加/修改键值对student['email'] = 'zhangsan@email.com'student['age'] = 21# 删除键值对del student['major']removed_value = student.pop('age')# 遍历字典(后面文章再做循环的介绍)for key, value in student.items(): print(f"{key}: {value}")# 获取所有键/值keys = student.keys()values = student.values()
五、集合(Set)- 无序不重复元素
5.1 创建集合
# 创建集合(使用花括号)empty_set = set() # 注意:{}创建的是空字典!numbers = {1, 2, 3, 4, 5}fruits = {'apple', 'banana', 'orange'}# 从列表去重numbers_list = [1, 2, 2, 3, 3, 3, 4, 4, 4, 4]unique_numbers = set(numbers_list) # {1, 2, 3, 4}
5.2 集合操作
A = {1, 2, 3, 4, 5}B = {4, 5, 6, 7, 8}# 基本操作A.add(6) # 添加元素A.remove(3) # 删除元素(不存在会报错)A.discard(10) # 删除元素(不存在不会报错)# 集合运算print(A | B) # 并集: {1, 2, 3, 4, 5, 6, 7, 8}print(A & B) # 交集: {4, 5}print(A - B) # 差集: {1, 2, 3}print(A ^ B) # 对称差集: {1, 2, 3, 6, 7, 8}
5.3 集合常用方法
# 判断子集/超集set1 = {1, 2, 3}set2 = {1, 2, 3, 4, 5}print(set1.issubset(set2)) # Trueprint(set2.issuperset(set1)) # True
六、四种数据结构对比
今天的内容先记录到这里。如果有不对或者需要补充的地方,欢迎指正。
如果你觉得文章写的还不错,不妨点赞、推荐,转发给你的朋友看一下。
后面的内容我会继续边学边记,慢慢把 Python 的基础走一遍。