Python万字长文基础教程第三章:数据结构

本章将深入探讨Python中三种基本且强大的数据结构:列表、元组和字典。这些数据结构为存储和操作数据提供了灵活而高效的方法。通过学习这些数据结构,可以更好地组织和管理程序中的数据,提高代码的效率和可读性。本章将详细介绍每种数据结构的特性、操作方法以及最佳实践,为后续的Python编程奠定坚实基础。

3.1 列表

列表是Python中最常用的数据结构之一,它是一个可变的、有序的元素集合。列表可以包含不同类型的元素,并且可以动态地增加或减少元素。

创建和访问列表

创建列表可以通过方括号[]list()函数实现。列表的元素可以通过索引访问,索引从0开始。负索引表示从列表末尾开始计数。

# 创建列表
fruits = ['apple', 'banana', 'cherry']
numbers = list(range(1, 6))

# 访问列表元素
print(fruits[0])  # 输出: apple
print(numbers[-1])  # 输出: 5

# 切片操作
print(fruits[1:3])  # 输出: ['banana', 'cherry']

在上面的代码中,首先创建了两个列表:一个水果列表和一个数字列表。然后通过索引访问了列表的元素,并演示了切片操作。切片操作可以获取列表的一部分,语法为list[start:end],其中start是起始索引(包含),end是结束索引(不包含)。

列表操作

列表支持多种操作,包括添加、删除和修改元素。

# 添加元素
fruits.append('date')
fruits.insert(1, 'blueberry')

# 删除元素
removed_fruit = fruits.pop()
fruits.remove('banana')

# 修改元素
fruits[0] = 'apricot'

print(fruits)  # 输出: ['apricot', 'blueberry', 'cherry']

列表连接和重复

# 列表连接和重复
new_list = fruits + numbers
repeated_list = fruits * 2

print(new_list)  # 输出: ['apricot', 'blueberry', 'cherry', 1, 2, 3, 4, 5]
print(repeated_list)  # 输出: ['apricot', 'blueberry', 'cherry', 'apricot', 'blueberry', 'cherry']

这段代码展示了列表的各种操作。append()方法在列表末尾添加元素,insert()方法在指定位置插入元素。pop()方法删除并返回最后一个元素,remove()方法删除指定的元素。通过索引赋值可以修改列表元素。列表还支持连接(+)和重复(*)操作。

列表推导式

列表推导式是一种简洁而强大的方式来创建新的列表。它可以替代传统的for循环,使代码更加简洁和易读。

# 使用for循环创建列表
squares = []
for x in range(10):
    squares.append(x**2)

# 使用列表推导式
squares_comp = [x**2 for x in range(10)]

print(squares)  # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]
print(squares_comp)  # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

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

这个例子展示了如何使用列表推导式创建一个包含平方数的列表。列表推导式的基本语法是[expression for item in iterable if condition]。它可以包含一个可选的条件语句,用于筛选元素。

列表是Python中极其versatile的数据结构,适用于存储和操作有序的数据集合。通过各种内置方法和操作,可以轻松地添加、删除、修改和访问列表元素。列表推导式提供了一种简洁的方式来创建和转换列表。掌握列表的使用对于高效的Python编程至关重要。

3.2 元组

元组是Python中另一种重要的序列数据类型。与列表不同,元组是不可变的,这意味着一旦创建,就不能修改其内容。这种特性使得元组在某些场景下特别有用,例如作为字典的键或者在多线程环境中使用。

创建和访问元组

元组可以通过圆括号()tuple()函数创建。元组的元素可以通过索引访问,与列表类似。

# 创建元组
coordinates = (10, 20)
rgb_color = tuple([255, 0, 128])

# 访问元组元素
print(coordinates[0])  # 输出: 10
print(rgb_color[-1])   # 输出: 128

# 尝试修改元组(会引发错误)
try:
    coordinates[0] = 15
except TypeError as e:
    print(f"错误: {e}")  # 输出: 错误: 'tuple' object does not support item assignment

在这个例子中,我们创建了两个元组:一个表示坐标,另一个表示RGB颜色值。通过索引可以访问元组的元素,但尝试修改元组会引发TypeError

元组的不可变性和应用场景

元组的不可变性使其成为存储固定数据集的理想选择。这种特性在某些情况下非常有用:

# 元组作为字典的键
student_grades = {
    ('Alice', 'Math'): 95,
    ('Alice', 'Physics'): 88,
    ('Bob', 'Math'): 75,
    ('Bob', 'Physics'): 82
}

print(student_grades[('Alice', 'Math')])  # 输出: 95

# 函数返回多个值
def get_dimensions():
    return (1920, 1080)

width, height = get_dimensions()
print(f"Width: {width}, Height: {height}")  # 输出: Width: 1920, Height: 1080

# 在循环中使用元组解包
for name, grade in [('Alice', 95), ('Bob', 75), ('Charlie', 80)]:
    print(f"{name}: {grade}")

这个示例展示了元组的几个常见用途:

  1. 作为字典的键,因为字典的键必须是不可变的。
  2. 函数返回多个值时,可以使用元组打包这些值。
  3. 在循环中使用元组解包,可以同时获取多个相关的值。

元组与列表的比较

虽然元组和列表看起来很相似,但它们有几个关键的区别:

import sys

# 创建包含相同元素的元组和列表
tuple_example = (1, 2, 3, 4, 5)
list_example = [1, 2, 3, 4, 5]

# 比较内存使用
print(f"元组占用内存: {sys.getsizeof(tuple_example)} bytes")
print(f"列表占用内存: {sys.getsizeof(list_example)} bytes")

# 比较操作速度
# 注意:下面的代码块在Markdown中无法执行,此处仅做示例
# %timeit x = tuple_example[2]
# %timeit y = list_example[2]

# 尝试修改
tuple_example += (6,)  # 创建新的元组
list_example.append(6)  # 修改现有列表

print(tuple_example)  # 输出: (1, 2, 3, 4, 5, 6)
print(list_example)   # 输出: [1, 2, 3, 4, 5, 6]

这个例子比较了元组和列表在内存使用和操作速度上的差异。通常,元组比列表占用更少的内存,并且在某些操作上更快。但是,当需要修改元组时,必须创建一个新的元组,而列表可以直接修改。

元组是Python中一种重要的不可变序列类型,适用于存储不应被修改的数据集。它的不可变性使其成为字典键的理想选择,并在多线程环境中提供了一定的安全性。元组通常比列表更节省内存,在某些操作上也更快。掌握元组的使用可以帮助编写更高效、更安全的Python代码。

3.3 字典

字典是Python中另一种非常重要的数据结构,它提供了一种key-value存储方式。字典是可变的、无序的(在Python 3.7+中会保持插入顺序)、不允许重复键的数据结构。字典在处理结构化数据时非常有用,例如配置信息、数据记录等。

创建和访问字典

字典可以通过花括号{}dict()函数创建。可以通过键来访问、添加或修改值。

# 创建字典
student = {'name': 'Alice', 'age': 20, 'major': 'Computer Science'}
grades = dict(math=95, physics=88, chemistry=92)

# 访问字典元素
print(student['name'])  # 输出: Alice
print(grades.get('math', 'N/A'))  # 输出: 95

# 添加或修改元素
student['gender'] = 'Female'
grades['biology'] = 90

print(student)  # 输出: {'name': 'Alice', 'age': 20, 'major': 'Computer Science', 'gender': 'Female'}
print(grades)   # 输出: {'math': 95, 'physics': 88, 'chemistry': 92, 'biology': 90}

在这个例子中,我们创建了两个字典:一个存储学生信息,另一个存储成绩。通过键可以直接访问字典的值。get()方法提供了一种安全的方式来访问字典元素,如果键不存在,它会返回一个默认值。可以通过简单的赋值来添加新的键值对或修改现有的值。

字典操作

字典支持多种操作,包括删除元素、检查键是否存在、获取所有的键或值等。

# 删除元素
del grades['physics']
removed_value = grades.pop('chemistry', 'N/A')

# 检查键是否存在
if 'age' in student:
    print(f"Age: {student['age']}")

# 获取所有的键和值
print(list(student.keys()))    # 输出: ['name', 'age', 'major', 'gender']
print(list(student.values()))  # 输出: ['Alice', 20, 'Computer Science', 'Female']

# 遍历字典
for key, value in student.items():
    print(f"{key}: {value}")

# 字典合并
student.update({'gpa': 3.8, 'year': 'Sophomore'})
print(student)

这个示例展示了几个常用的字典操作:

  1. 使用del关键字或pop()方法删除元素。
  2. 使用in关键字检查键是否存在。
  3. 使用keys()values()items()方法获取字典的键、值和键值对。
  4. 使用for循环遍历字典。
  5. 使用update()方法合并字典或添加多个键值对。

字典推导式

类似于列表推导式,字典也支持推导式,这提供了一种简洁的方式来创建新的字典。

# 使用字典推导式创建平方数字典
squares = {x: x**2 for x in range(5)}
print(squares)  # 输出: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 条件字典推导式
even_squares = {x: x**2 for x in range(10) if x % 2 == 0}
print(even_squares)  # 输出: {0: 0, 2: 4, 4: 16, 6: 36, 8: 64}

# 从两个列表创建字典
keys = ['a', 'b', 'c', 'd']
values = [1, 2, 3, 4]
my_dict = {k: v for k, v in zip(keys, values)}
print(my_dict)  # 输出: {'a': 1, 'b': 2, 'c': 3, 'd': 4}

字典推导式提供了一种简洁的方式来创建字典。它的基本语法是{key_expression: value_expression for item in iterable}。这个例子展示了如何使用字典推导式创建平方数字典、带条件的字典,以及如何从两个列表创建字典。

高级字典用法

Python的字典还有一些高级用法,例如默认字典和有序字典。

from collections import defaultdict, OrderedDict

# 默认字典
word_count = defaultdict(int)
words = ["apple", "banana", "apple", "cherry", "banana", "date"]
for word in words:
    word_count[word] += 1

print(dict(word_count))  # 输出: {'apple': 2, 'banana': 2, 'cherry': 1, 'date': 1}

# 有序字典
ordered_grades = OrderedDict()
ordered_grades['Math'] = 95
ordered_grades['Physics'] = 88
ordered_grades['Chemistry'] = 92

for subject, grade in ordered_grades.items():
    print(f"{subject}: {grade}")

# 字典的键必须是不可变类型
try:
    invalid_dict = {[1, 2]: "This won't work"}
except TypeError as e:
    print(f"错误: {e}")  # 输出: 错误: unhashable type: 'list'

# 使用元组作为字典的键
valid_dict = {(1, 2): "This works"}
print(valid_dict[(1, 2)])  # 输出: This works

这个例子展示了几个高级的字典用法:

  1. defaultdict:一种特殊的字典,当访问不存在的键时,它会自动创建一个默认值。在这个例子中,我们用它来计算单词出现的次数。
  2. OrderedDict:一种保持键插入顺序的字典。虽然从Python 3.7开始普通字典也保持插入顺序,但OrderedDict在某些特定场景下仍然有用。
  3. 字典键的限制:字典的键必须是不可变(可哈希)的类型。尝试使用可变类型(如列表)作为键会引发TypeError。相反,元组是不可变的,所以可以用作字典的键。

字典的应用场景

字典在Python编程中有广泛的应用,以下是一些常见的使用场景:

# 配置管理
config = {
    'database': {
        'host': 'localhost',
        'port': 5432,
        'user': 'admin',
        'password': 'secret'
    },
    'api': {
        'url': 'https://api.example.com', 
        'key': 'your-api-key'
    }
}

# 缓存/记忆化
from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print(fibonacci(100))  # 快速计算大型斐波那契数

# 计数器
from collections import Counter

text = "to be or not to be that is the question"
word_counts = Counter(text.split())
print(word_counts)

# 图形表示
graph = {
    'A': {'B', 'C'},
    'B': {'A', 'D', 'E'},
    'C': {'A', 'F'},
    'D': {'B'},
    'E': {'B', 'F'},
    'F': {'C', 'E'}
}

# 深度优先搜索
def dfs(graph, start, visited=None):
    if visited is None:
        visited = set()
    visited.add(start)
    print(start, end=' ')
    for next in graph[start] - visited:
        dfs(graph, next, visited)
    return visited

dfs(graph, 'A')  # 输出: A B D E F C

这个例子展示了字典在不同场景下的应用:

  1. 配置管理:使用嵌套字典存储复杂的配置信息。
  2. 缓存/记忆化:使用字典存储已计算的结果,避免重复计算。
  3. 计数器:使用Counter类(基于字典)快速计算元素出现的次数。
  4. 图形表示:使用字典表示图形结构,其中键是节点,值是相邻节点的列表。

字典是Python中极其强大和灵活的数据结构,适用于存储和操作键值对数据。它提供了快速的查找、插入和删除操作,使其成为处理结构化数据的理想选择。通过掌握字典的基本操作、推导式和高级用法,可以大大提高代码的效率和可读性。字典在配置管理、缓存、计数、图形表示等多种场景下都有广泛应用。理解和熟练使用字典是成为高效Python程序员的关键步骤之一。

本章总结

本章深入探讨了Python中三种核心数据结构:列表、元组和字典。这些数据结构为组织和操作数据提供了强大而灵活的工具。列表作为可变序列,适用于存储和修改有序数据集合。元组作为不可变序列,提供了数据完整性保证,特别适合作为字典的键或在多线程环境中使用。字典则提供了高效的键值对存储方式,广泛应用于各种数据处理

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值