Python核心数据结构与函数编程
Python的魅力在于其简洁而强大的内置数据类型和灵活的函数编程能力。本文将带你探索列表、元组、字典等核心数据结构,并掌握函数编程的精髓,让你能够优雅地解决复杂问题。
1. 从实际问题出发:小明的工作选择难题
问题背景
大四学生小明收到了2家公司的工作邀请:
- 公司A:成都
- 公司B:绵阳
面对选择困难,我们可以用Python来帮助小明做决定!
基础解决方案:if…else…
import randomdef choose_company_basic():companies = ['成都公司A', '绵阳公司B']choice = random.choice(companies)return f"恭喜!建议选择:{choice}"print(choose_company_basic())
扩展问题:6家公司如何选择?
def choose_company_advanced():companies = ['成都公司A', '绵阳公司B', '北京公司C', '上海公司D', '广州公司E', '深圳公司F']choice = random.choice(companies)return f"在6家公司中,抽中的是:{choice}"print(choose_company_advanced())
更优雅的解决方案:使用列表
def smart_choice(companies):"""智能选择工作地点"""print("可选公司列表:", companies)chosen = random.choice(companies)return f"经过随机选择,建议去:{chosen}"# 使用示例
company_list = ["成都腾讯", "绵阳华为", "北京百度", "上海阿里", "广州网易", "深圳字节"]
result = smart_choice(company_list)
print(result)
2. 列表(List)
列表的创建与基本操作
# 创建列表的多种方式
empty_list = [] # 空列表
numbers = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] # 数字列表
mixed_list = [1, "hello", 3.14, True] # 混合类型列表
from_range = list(range(10)) # 从range创建
from_string = list("Python") # 从字符串创建print("数字列表:", numbers)
print("混合列表:", mixed_list)
print("范围列表:", from_range)
print("字符串转换:", from_string)
output:
数字列表: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
混合列表: [1, 'hello', 3.14, True]
范围列表: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
字符串转换: ['P', 'y', 't', 'h', 'o', 'n']
列表索引与切片
ls = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]# 基本索引
print("ls[3] =", ls[3]) # 输出: 3
print("ls[-2] =", ls[-2]) # 输出: 8# 切片操作 [start:end]
print("ls[2:6] =", ls[2:6]) # 输出: [2, 3, 4, 5]
print("ls[:4] =", ls[:4]) # 输出: [0, 1, 2, 3]
print("ls[7:] =", ls[7:]) # 输出: [7, 8, 9]# 带步长的切片 [start:end:step]
print("ls[1:8:2] =", ls[1:8:2]) # 输出: [1, 3, 5, 7]
print("ls[::3] =", ls[::3]) # 输出: [0, 3, 6, 9]
print("ls[::-1] =", ls[::-1]) # 输出: [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
列表常用方法
fruits = ['apple', 'banana']# 添加元素
fruits.append('orange') # 末尾添加
fruits.insert(1, 'grape') # 指定位置插入
fruits.extend(['pear', 'kiwi']) # 扩展列表print("添加后:", fruits) # ['apple', 'grape', 'banana', 'orange', 'pear', 'kiwi']# 删除元素
removed = fruits.pop() # 删除末尾元素
print(f"删除了: {removed}") # 删除了: kiwi
fruits.remove('grape') # 删除指定元素
print("删除后:", fruits) # ['apple', 'banana', 'orange', 'pear']# 其他操作
fruits.sort() # 排序
print("排序后:", fruits) # ['apple', 'banana', 'orange', 'pear']
fruits.reverse() # 反转
print("反转后:", fruits) # ['pear', 'orange', 'banana', 'apple']# 查找和统计
print("apple的位置:", fruits.index('apple')) # 3
print("orange出现次数:", fruits.count('orange')) # 1
列表相关函数
numbers = [3, 1, 4, 1, 5, 9, 2, 6]print("列表长度:", len(numbers))
print("最大值:", max(numbers))
print("最小值:", min(numbers))
print("求和:", sum(numbers))
print("排序:", sorted(numbers))# 字符串转列表
text = "Python编程"
char_list = list(text)
print("字符串转列表:", char_list) # ['P', 'y', 't', 'h', 'o', 'n', '编', '程']
output:
列表长度: 8
最大值: 9
最小值: 1
求和: 31
排序: [1, 1, 2, 3, 4, 5, 6, 9]
字符串转列表: ['P', 'y', 't', 'h', 'o', 'n', '编', '程']
3. 元组(Tuple)
元组的创建与特性
# 创建元组
empty_tuple = () # 空元组
single_tuple = (42,) # 单元素元组(注意逗号)
numbers_tuple = (1, 2, 3, 4, 5) # 数字元组
mixed_tuple = (1, "hello", 3.14, True) # 混合元组print("数字元组:", numbers_tuple)
print("混合元组:", mixed_tuple)# 元组的不可变性
try:numbers_tuple[0] = 10 # 这会抛出错误
except TypeError as e:print("错误:", e) # 'tuple' object does not support item assignment
output:
数字元组: (1, 2, 3, 4, 5)
混合元组: (1, 'hello', 3.14, True)
错误: 'tuple' object does not support item assignment
元组解包与转换
# 元组解包
person = ("张三", 25, "工程师")
name, age, job = person # 解包
print(f"姓名:{name}, 年龄:{age}, 职业:{job}")# 函数返回多个值(实际上是返回元组)
def get_circle_info(radius):area = 3.14159 * radius ** 2circumference = 2 * 3.14159 * radiusreturn area, circumference # 返回元组circle_area, circle_circumference = get_circle_info(5)
print(f"面积: {circle_area:.2f}, 周长: {circle_circumference:.2f}")# 元组与列表转换
tuple_data = (1, 2, 3)
list_data = list(tuple_data) # 元组转列表
new_tuple = tuple(list_data) # 列表转元组print("元组转列表:", list_data)
print("列表转元组:", new_tuple)
output:
姓名:张三, 年龄:25, 职业:工程师
面积: 78.54, 周长: 31.42
元组转列表: [1, 2, 3]
列表转元组: (1, 2, 3)
4. 字典(Dict)
字典的创建与基本操作
# 创建字典
empty_dict = {} # 空字典
student = {"name": "李四","age": 20,"major": "计算机科学","grades": [85, 92, 78]
}# 访问元素
print("姓名:", student["name"])
print("年龄:", student.get("age"))
print("不存在的键:", student.get("address", "未知")) # 提供默认值# 添加和修改
student["email"] = "lisi@email.com" # 添加新键
student["age"] = 21 # 修改值# 删除元素
removed_grade = student.pop("grades") # 删除并返回删除的值
del student["email"] # 删除键print("更新后的学生信息:", student)
output:
姓名: 李四
年龄: 20
不存在的键: 未知
更新后的学生信息: {'name': '李四', 'age': 21, 'major': '计算机科学'}
字典的遍历与操作
# 遍历字典
scores = {"数学": 90, "英语": 85, "编程": 95, "物理": 88}print("所有科目:")
for subject in scores.keys():print("-", subject)print("所有成绩:")
for score in scores.values():print("-", score)print("科目和成绩:")
for subject, score in scores.items():print(f"{subject}: {score}分")# 字典推导式
squared_dict = {x: x**2 for x in range(1, 6)}
print("平方字典:", squared_dict) # {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
output:
所有科目:
- 数学
- 英语
- 编程
- 物理
所有成绩:
- 90
- 85
- 95
- 88
科目和成绩:
数学: 90分
英语: 85分
编程: 95分
物理: 88分
平方字典: {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
实际应用:单词字典排序
def create_word_dict(words):"""将单词列表按首字母分类到字典"""word_dict = {}for word in words:first_char = word[0].lower() # 获取首字母并转为小写# 使用setdefault确保键存在word_dict.setdefault(first_char, []).append(word)return word_dict# 使用示例
word_list = ["apple", "banana", "apricot", "blueberry", "cherry", "avocado"]
sorted_words = sorted(word_list) # 先按字母顺序排序
word_dict = create_word_dict(sorted_words)print("按首字母分类的单词字典:")
for letter, words in word_dict.items():print(f"{letter}: {words}")
output:
按首字母分类的单词字典:
a: ['apple', 'apricot', 'avocado']
b: ['banana', 'blueberry']
c: ['cherry']
5. 函数编程
为什么使用函数?
- 分而治之:将复杂任务分解为简单、功能单一的小任务
- 信息隐藏:使用者只关心功能和接口,不关心内部实现
- 代码复用:避免重复代码,提高开发效率
- 易于维护:模块化设计,便于调试和修改
函数定义基础
# 无参数函数
def greet():"""简单的问候函数"""print("Hello, World!")return # 可选的return语句# 多参数函数
def multiply(a, b):"""计算两个数的乘积"""result = a * breturn result# 使用函数
greet()
product = multiply(5, 3)
print(f"5 * 3 = {product}")
output:
Hello, World!
5 * 3 = 15
可选参数与默认值
def math_operation(n, operation='factorial'):"""数学运算函数operation: 'factorial'计算阶乘, 'sum'计算求和"""if operation == 'factorial':result = 1for i in range(1, n + 1):result *= ireturn f"{n}的阶乘 = {result}"elif operation == 'sum':result = sum(range(1, n + 1))return f"1到{n}的和 = {result}"else:return "未知操作"# 使用示例
print(math_operation(5)) # 默认计算阶乘
print(math_operation(5, 'factorial')) # 显式指定阶乘
print(math_operation(5, 'sum')) # 计算求和
output:
5的阶乘 = 120
5的阶乘 = 120
1到5的和 = 15
处理组合参数
def process_string(text, uppercase=True, reverse=False):"""字符串处理函数"""if uppercase:text = text.upper()if reverse:text = text[::-1]return text# 多种调用方式
print(process_string("hello")) # HELLO
print(process_string("hello", False)) # hello
print(process_string("hello", True, True)) # OLLEH
局部变量与全局变量
global_var = "我是全局变量"def variable_demo():# 修改全局变量需要使用global关键字global global_varlocal_var = "我是局部变量"print("函数内访问局部变量:", local_var)print("函数内访问全局变量:", global_var)global_var = "修改后的全局变量"variable_demo()
print("函数外访问全局变量:", global_var)
# print("函数外访问局部变量:", local_var) # 这会报错,local_var未定义
output:
函数内访问局部变量: 我是局部变量
函数内访问全局变量: 我是全局变量
函数外访问全局变量: 修改后的全局变量
6. 高级函数特性
参数传递方式
# 位置参数
def introduce(name, age, city):return f"我叫{name},今年{age}岁,来自{city}"# 关键字参数
def create_profile(name, age, email, city="未知"):return {"name": name,"age": age,"email": email,"city": city}# 使用示例
print(introduce("张三", 25, "北京")) # 位置参数
print(create_profile(age=30, name="李四", email="lisi@email.com")) # 关键字参数
output:
我叫张三,今年25岁,来自北京
{'name': '李四', 'age': 30, 'email': 'lisi@email.com', 'city': '未知'}
Lambda匿名函数
# 普通函数 vs Lambda函数
def square(x):return x ** 2square_lambda = lambda x: x ** 2print("普通函数:", square(5)) # 25
print("Lambda函数:", square_lambda(5)) # 25# Lambda与map结合
numbers = [1, 2, 3, 4, 5]
squared = list(map(lambda x: x ** 2, numbers))
print("平方列表:", squared) # [1, 4, 9, 16, 25]# 复杂Lambda应用
students = [("Alice", 85), ("Bob", 92), ("Charlie", 78)]
top_students = list(filter(lambda s: s[1] > 80, students))
print("高分学生:", top_students) # [('Alice', 85), ('Bob', 92)]
output:
普通函数: 25
Lambda函数: 25
平方列表: [1, 4, 9, 16, 25]
高分学生: [('Alice', 85), ('Bob', 92)]
跨文件函数调用
# file_1.py
"""
file_1.py - 工具函数库
"""def calculate_bmi(weight, height):"""计算BMI指数"""return weight / (height ** 2)def bmi_category(bmi):"""根据BMI分类"""if bmi < 18.5:return "偏轻"elif bmi < 24:return "正常"elif bmi < 28:return "超重"else:return "肥胖"# file_2.py
"""
file_2.py - 主程序文件
"""
# from file_1 import calculate_bmi, bmi_category# 使用示例
# weight = 70 # 公斤
# height = 1.75 # 米
# bmi = calculate_bmi(weight, height)
# category = bmi_category(bmi)
# print(f"BMI: {bmi:.1f}, 分类: {category}")
7. 实战练习:素数计算
def is_prime(n):"""判断一个数是否为素数"""if n <= 1:return Falseif n == 2:return Trueif n % 2 == 0:return False# 检查从3到sqrt(n)的奇数for i in range(3, int(n**0.5) + 1, 2):if n % i == 0:return Falsereturn Truedef prime_statistics(n):"""统计n以内的素数返回:素数列表,素数个数,素数和"""primes = []prime_count = 0prime_sum = 0for num in range(2, n + 1):if is_prime(num):primes.append(num)prime_count += 1prime_sum += numreturn primes, prime_count, prime_sum# 使用示例
limit = 100
primes, count, total = prime_statistics(limit)print(f"{limit}以内的素数有{count}个:")
print("素数列表:", primes)
print(f"素数总和: {total}")# 前20个素数
first_20_primes = primes[:20]
print(f"前20个素数: {first_20_primes}")
output:
100以内的素数有25个:
素数列表: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97]
素数总和: 1060
前20个素数: [2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71]
总结
通过本文的学习,你应该已经掌握了:
核心数据结构
- 列表:可变序列,支持丰富的操作方法
- 元组:不可变序列,适合保护数据完整性
- 字典:键值对映射,快速查找和存储
函数编程精髓
- 函数定义:参数传递、返回值、作用域
- 高级特性:默认参数、lambda函数、函数式编程
- 设计原则:模块化、信息隐藏、代码复用
实际应用能力
- 使用合适的数据结构解决实际问题
- 编写可复用、易维护的函数
- 理解Python的函数式编程范式