python 数据结构详细教学

为什么学习数据结构?

数据结构的重要性

在编程的世界里,数据是核心。无论是简单的应用程序还是复杂的企业级系统,处理和管理数据都是必不可少的任务。数据结构就是一种特定的方式或格式来组织、管理和存储数据,以便可以高效地访问和修改这些数据。选择合适的数据结构对于编写高效的程序至关重要

  • 提高效率:正确选择的数据结构能够显著提升算法的性能。例如,使用哈希表(字典)查找元素的速度远快于遍历列表
  • 简化代码:良好的数据结构可以帮助我们写出更简洁、易读且易于维护的代码。比如,集合可以轻松实现去重功能,而不需要编写复杂的逻辑
  • 解决问题的能力:掌握多种数据结构意味着你有更多的工具来解决各种编程问题。不同的数据结构适用于不同类型的问题,了解它们可以让你更好地应对挑战

Python 中的数据结构概述

Python 提供了丰富的内置数据结构,使得开发者能够快速有效地处理各种类型的数据。以下是 Python 中最常用的一些数据结构:

  • 列表(List):有序且可变的序列,允许重复元素。非常适合用于需要频繁添加或删除元素的情况
  • 元组(Tuple):与列表类似,但不可变。常用于表示固定数量的相关值,如坐标点或数据库记录
  • 字典(Dictionary):无序的键值对集合,提供快速查找的能力。广泛应用于关联数组或映射关系中
  • 集合(Set):无序且不包含重复元素的集合。常用于数学运算或去除重复项

除了这些基本的数据结构外,Python 还提供了其他高级数据结构,如栈(Stack)、队列(Queue)、双端队列(Deque)和堆(Heap)。这些结构虽然不是 Python 的内置类型,但可以通过标准库模块轻松实现

选择合适的数据结构

理解何时以及如何选择合适的数据结构是一个关键技能。以下是一些考虑因素:

  • 操作频率:某些数据结构更适合频繁插入或删除操作,而另一些则擅长快速查找
  • 内存占用:不同数据结构对内存的需求各不相同,选择时应考虑到系统的资源限制
  • 应用场景:根据具体任务的需求选择最合适的数据结构。例如,在实现缓存机制时,可能需要使用 LRU 缓存(Least Recently Used),这通常由双端队列结合字典来实现

学习目标

通过本课程的学习,你将能够:

  • 理解并熟练运用 Python 内置的基本数据结构(列表、元组、字典、集合)
  • 掌握如何根据实际需求选择合适的数据结构
  • 学会使用 Python 标准库提供的高级数据结构(如 collections 和 queue 模块)
  • 通过实践项目加深对数据结构的理解,并能灵活应用到自己的项目中

列表(List)

列表是 Python 中最常用的数据结构之一,它是一种有序且可变的序列,允许存储不同类型的元素,并支持重复值。列表非常适合用于需要频繁添加、删除或访问元素的情况

创建列表

你可以通过多种方式创建列表:

  • 空列表:使用方括号 []list() 函数

empty_list = []
also_empty_list = list()
  • 预填充列表:直接在方括号内列出元素
fruits = ['apple', 'banana', 'cherry']
numbers = [1, 2, 3, 4, 5]
mixed_list = ['apple', 1, True, {'key': 'value'}]  # 可以包含不同类型的数据
  • 从其他可迭代对象创建列表:使用 list() 函数将字符串、元组等转换为列表
string_to_list = list('hello')  # 输出: ['h', 'e', 'l', 'l', 'o']
tuple_to_list = list((1, 2, 3))  # 输出: [1, 2, 3]

 访问列表元素

列表中的元素可以通过索引访问,索引从 0 开始。你还可以使用负数索引来从列表末尾开始计数

索引访问

fruits = ['apple', 'banana', 'cherry']

print(fruits[0])    # 输出: apple
print(fruits[-1])   # 输出: cherry

切片操作

切片可以获取子列表,语法为 list[start:end:step],其中 start 是起始索引(包含),end 是结束索引(不包含),step 是步长(默认为 1)

numbers = [0, 1, 2, 3, 4, 5]

print(numbers[1:4])     # 输出: [1, 2, 3]
print(numbers[:3])      # 输出: [0, 1, 2]
print(numbers[2:])      # 输出: [2, 3, 4, 5]
print(numbers[::2])     # 输出: [0, 2, 4]
print(numbers[::-1])    # 输出: [5, 4, 3, 2, 1, 0]

修改列表

列表是可变的数据结构,这意味着可以在创建后修改其内容

添加元素

append():在列表末尾添加一个元素

fruits.append('date')
print(fruits)  # 输出: ['apple', 'banana', 'cherry', 'date']

insert():在指定位置插入一个元素

fruits.insert(1, 'berry')
print(fruits)  # 输出: ['apple', 'berry', 'banana', 'cherry', 'date']

extend():将另一个可迭代对象的所有元素添加到列表末尾

fruits.extend(['fig', 'grape'])
print(fruits)  # 输出: ['apple', 'berry', 'banana', 'cherry', 'date', 'fig', 'grape']

删除元素

remove():移除第一个匹配项。如果元素不存在,会抛出 ValueError

fruits.remove('banana')
print(fruits)  # 输出: ['apple', 'berry', 'cherry', 'date', 'fig', 'grape']

pop():移除并返回指定索引处的元素,默认移除最后一个元素

last_fruit = fruits.pop()
print(last_fruit)  # 输出: grape
print(fruits)      # 输出: ['apple', 'berry', 'cherry', 'date', 'fig']

del 语句:根据索引或切片删除元素

del fruits[1]  # 删除索引为 1 的元素
print(fruits)  # 输出: ['apple', 'cherry', 'date', 'fig']

del fruits[1:3]  # 删除索引为 1 和 2 的元素
print(fruits)    # 输出: ['apple', 'fig']

修改元素

可以直接通过索引赋值来修改列表中的元素

fruits[0] = 'orange'
print(fruits)  # 输出: ['orange', 'fig']

遍历列表

遍历列表可以使用 for 循环,这有助于对每个元素进行处理

for fruit in fruits:
    print(fruit)

# 使用 enumerate 获取索引和元素
for index, fruit in enumerate(fruits):
    print(f"Index {index}: {fruit}")

列表推导式

列表推导式提供了一种简洁的方式来创建新的列表,通常用于基于现有列表生成新列表

squares = [x**2 for x in range(5)]
print(squares)  # 输出: [0, 1, 4, 9, 16]

# 带条件的列表推导式
even_squares = [x**2 for x in range(10) if x % 2 == 0]
print(even_squares)  # 输出: [0, 4, 16, 36, 64]

列表排序

Python 提供了两种主要的方式对列表进行排序:sort() 方法和 sorted() 函数。

  • sort():就地排序,直接修改原列表

numbers = [3, 1, 4, 1, 5, 9]
numbers.sort()
print(numbers)  # 输出: [1, 1, 3, 4, 5, 9]
  • sorted():返回一个新的已排序列表,原列表保持不变
sorted_numbers = sorted(numbers)
print(sorted_numbers)  # 输出: [1, 1, 3, 4, 5, 9]
print(numbers)         # 输出: [3, 1, 4, 1, 5, 9]
  • 自定义排序:可以传递 key 参数来指定排序依据
    • iterable:要排序的可迭代对象。
    • key_func:一个函数,接收一个元素并返回一个用于排序的键
words = ['apple', 'banana', 'cherry', 'date']
sorted_words = sorted(words, key=len)
print(sorted_words)  # 输出: ['date', 'apple', 'banana', 'cherry']

按字符串长度排序

假设我们有一个包含单词的列表,想要按照每个单词的长度进行排序

words = ['apple', 'banana', 'cherry', 'date']

# 使用 len 函数作为 key 来按单词长度排序
sorted_words = sorted(words, key=len)

print(sorted_words)  # 输出: ['date', 'apple', 'banana', 'cherry']

在这个例子中,len 函数被用作 key 参数。对于每个单词,len 函数计算其字符数,然后根据这些数值对单词进行排序

按对象的属性排序

如果列表中的元素是更复杂的数据结构(如字典或对象),我们可以使用 lambda 表达式或 operator.itemgetter 来指定排序依据

按字典的值排序
people = [
    {'name': 'Alice', 'age': 30},
    {'name': 'Bob', 'age': 25},
    {'name': 'Charlie', 'age': 35}
]

# 使用 lambda 表达式按年龄排序
sorted_people_by_age = sorted(people, key=lambda person: person['age'])

print(sorted_people_by_age)
# 输出:
# [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]
使用 operator.itemgetter 排序

Python 的 operator 模块提供了 itemgetter 函数,可以更简洁地实现同样的功能

from operator import itemgetter

people = [
    {'name': 'Alice', 'age': 30},
    {'name': 'Bob', 'age': 25},
    {'name': 'Charlie', 'age': 35}
]

sorted_people_by_age = sorted(people, key=itemgetter('age'))

print(sorted_people_by_age)
# 输出:
# [{'name': 'Bob', 'age': 25}, {'name': 'Alice', 'age': 30}, {'name': 'Charlie', 'age': 35}]

itemgetter('age') 创建了一个函数,该函数从字典中提取 'age' 键的值,作为排序的依据

按多个条件排序

有时我们需要根据多个属性来排序。可以通过传递一个包含多个键的 tuplekey 参数来实现这一点

students = [
    {'name': 'Alice', 'grade': 88, 'age': 22},
    {'name': 'Bob', 'grade': 92, 'age': 21},
    {'name': 'Charlie', 'grade': 88, 'age': 23}
]

# 先按成绩降序排序,再按年龄升序排序
sorted_students = sorted(students, key=lambda student: (-student['grade'], student['age']))

print(sorted_students)
# 输出:
# [{'name': 'Bob', 'grade': 92, 'age': 21}, {'name': 'Alice', 'grade': 88, 'age': 22}, {'name': 'Charlie', 'grade': 88, 'age': 23}]

在这个例子中,(-student['grade'], student['age']) 返回一个元组,其中第一个元素是负的成绩(确保成绩高的排在前面),第二个元素是年龄。这样,首先会根据成绩排序,当成绩相同时,再根据年龄排序

按对象方法的结果排序

如果我们有一个类的对象列表,还可以根据对象的方法结果进行排序

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def get_initial(self):
        return self.name[0] if self.name else ''

people = [Person('Alice', 30), Person('Bob', 25), Person('Charlie', 35)]

# 按名字首字母排序
sorted_people_by_initial = sorted(people, key=lambda person: person.get_initial())

for person in sorted_people_by_initial:
    print(f"{person.name}: {person.age}")
# 输出:
# Alice: 30
# Bob: 25
# Charlie: 35

在这个例子中,lambda person: person.get_initial() 提取每个 Person 对象的名字首字母,并根据这个值进行排序

列表的常见操作

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

校园日记

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值