Python的康复训练
长时间没写 Python,直接让 Claude跑了篇康复训练笔记给我 XD
第一章:Python基础语法 本章主要介绍Python语言的基本语法。熟悉这些基础知识是进行任何编程活动的前提。
1.1 变量与数据类型 在Python中,变量是存储数据的容器。Python是动态类型语言,这意味着我们不需要显式声明变量的类型。
1.1.1 基本数据类型
整数(int)
1 2 3 4 5 a = 5 b = 0b1010 c = 0o12 d = 0xA big_num = 1_000_000
浮点数(float)
1 2 3 pi = 3.14159 e = 2.71828 scientific = 3.14e-10
字符串(str)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 name = "Python" message = 'Hello, World!' multi_line = """这是第一行 这是第二行 这是第三行""" name = "Alice" age = 25 print (f"My name is {name} and I am {age} years old" )print ("My name is {} and I am {} years old" .format (name, age))print ("My name is %s and I am %d years old" % (name, age))
布尔值(bool)
1 2 3 4 5 6 is_active = True is_empty = False print (True and False ) print (True or False ) print (not True )
1.1.2 类型转换 Python提供了多种类型转换函数:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 str_num = "123" num = int (str_num) float_num = float (str_num) num = 123 str_num = str (num) print (type (123 )) print (type ("hello" )) print (type (3.14 )) print (type (True )) print (isinstance (123 , int )) print (isinstance ("hello" , str ))
1.1.3 变量命名规则
变量名只能包含字母、数字和下划线
变量名必须以字母或下划线开头
变量名区分大小写
不能使用Python关键字
1 2 3 4 5 6 7 8 9 user_name = "Alice" age1 = 25 _private = "private variable"
1.2 数据结构 Python内置了丰富的数据结构,每种数据结构都有其特定的使用场景和优势。
1.2.1 列表(List) 列表是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 numbers = [1 , 2 , 3 , 4 , 5 ] mixed = [1 , "hello" , 3.14 , True ] empty_list = [] list_from_range = list (range (5 )) lst = [10 , 20 , 30 , 40 , 50 ] print (lst[0 ]) print (lst[-1 ]) print (lst[1 :3 ]) print (lst[::2 ]) print (lst[::-1 ]) lst = [1 , 2 , 3 ] lst.append(4 ) lst.insert(1 , 5 ) lst.extend([6 , 7 ]) lst.remove(5 ) popped = lst.pop() lst.sort() lst.reverse() index = lst.index(3 ) count = lst.count(2 ) squares = [x**2 for x in range (5 )] evens = [x for x in range (10 ) if x % 2 == 0 ]
1.2.2 元组(Tuple) 元组是不可变的序列类型,一旦创建就不能修改。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 point = (3 , 4 ) single_element = (1 ,) empty_tuple = () tuple_from_list = tuple ([1 , 2 , 3 ]) x, y = point a, *rest, b = (1 , 2 , 3 , 4 , 5 ) coordinates = (1 , 2 ) + (3 , 4 ) repeated = (1 , 2 ) * 3 exists = 3 in (1 , 2 , 3 ) tup = (1 , 2 , 2 , 3 , 4 ) count = tup.count(2 ) index = tup.index(3 )
1.2.3 集合(Set) 集合是无序的、不重复元素的集合,支持数学运算。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 numbers = {1 , 2 , 3 , 4 , 5 } set_from_list = set ([1 , 2 , 2 , 3 ]) empty_set = set () s1 = {1 , 2 , 3 } s2 = {3 , 4 , 5 } print (s1 | s2) print (s1 & s2) print (s1 - s2) print (s1 ^ s2) s = {1 , 2 , 3 } s.add(4 ) s.update([4 , 5 , 6 ]) s.remove(4 ) s.discard(4 ) popped = s.pop() s.clear()
1.2.4 字典(Dictionary) 字典是键值对的集合,提供了高效的查找机制。
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 person = { "name" : "Alice" , "age" : 25 , "skills" : ["Python" , "Java" ] } dict_from_pairs = dict ([("a" , 1 ), ("b" , 2 )]) empty_dict = {} print (person["name" ]) person["age" ] = 26 person["location" ] = "New York" value = person.get("salary" , 0 ) keys = person.keys() values = person.values() items = person.items() person.update({"salary" : 5000 }) popped = person.pop("age" ) person.clear() squares = {x: x**2 for x in range (5 )} employees = { "emp1" : {"name" : "John" , "salary" : 5000 }, "emp2" : {"name" : "Alice" , "salary" : 6000 } }
1.3 控制结构 Python提供了多种控制结构来控制程序的执行流程。
1.3.1 条件语句(if) 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 age = 20 if age >= 18 : print ("成年人" ) elif age >= 12 : print ("青少年" ) else : print ("儿童" ) status = "成年" if age >= 18 else "未成年" score = 85 is_student = True if score >= 60 and is_student: print ("及格" ) grade = "A" if score >= 90 else "B" if score >= 80 else "C" if score >= 70 else "D" fruits = ["apple" , "banana" , "orange" ] if "apple" in fruits: print ("有苹果" ) x = None if x is None : print ("x是None" ) empty_list = [] if not empty_list: print ("列表为空" )
1.3.2 for循环 Python的for循环可以遍历任何可迭代对象。
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 for i in range (5 ): print (i) fruits = ["apple" , "banana" , "orange" ] for fruit in fruits: print (fruit) for index, fruit in enumerate (fruits): print (f"索引 {index} : {fruit} " ) person = {"name" : "Alice" , "age" : 25 } for key in person: print (f"{key} : {person[key]} " ) for key, value in person.items(): print (f"{key} : {value} " ) for i in range (3 ): for j in range (3 ): print (f"({i} , {j} )" , end=" " ) print () squares = [x**2 for x in range (5 )] names = ["Alice" , "Bob" , "Charlie" ] ages = [25 , 30 , 35 ] for name, age in zip (names, ages): print (f"{name} is {age} years old" )
1.3.3 while循环 while循环在条件为真时重复执行代码块。
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 count = 0 while count < 5 : print (count) count += 1 while True : response = input ("请输入'quit'退出: " ) if response.lower() == 'quit' : break print (f"你输入了: {response} " ) number = 0 while number < 3 : print (number) number += 1 else : print ("循环正常结束" ) import timecountdown = 5 while countdown > 0 : print (countdown) countdown -= 1 time.sleep(1 ) print ("发射!" )
1.3.4 循环控制语句 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 for i in range (10 ): if i == 5 : break print (i) for i in range (5 ): if i == 2 : continue print (i) for i in range (3 ): if i == 1 : pass else : print (i) for i in range (3 ): print (i) else : print ("循环正常完成" ) for i in range (3 ): for j in range (3 ): if i == j: continue print (f"({i} , {j} )" , end=" " ) print ()
1.3.5 异常处理 虽然这通常在后面的章节介绍,但基本的异常处理也是控制流的重要部分:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 try : number = int (input ("请输入一个数字: " )) result = 10 / number print (f"结果是: {result} " ) except ValueError: print ("输入必须是数字" ) except ZeroDivisionError: print ("不能除以零" ) except Exception as e: print (f"发生错误: {e} " ) else : print ("计算成功完成" ) finally : print ("无论如何都会执行这里" )
第二章:函数与模块 2.1 函数的定义与调用 函数是可重用的代码块,它可以接收参数、执行特定任务并返回结果。
2.1.1 基本函数定义 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 def greet (name ): """ 向指定的人打招呼 Args: name: 人名 Returns: 打招呼的字符串 """ return f"Hello, {name} !" print (greet("Alice" )) def get_coordinates (): x = 10 y = 20 return x, y x, y = get_coordinates()
2.1.2 函数参数 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 def power (base, exponent ): return base ** exponent print (power(2 , 3 )) def greet (name, greeting="Hello" ): return f"{greeting} , {name} !" print (greet("Alice" )) print (greet("Bob" , "Hi" )) def create_profile (name, age, city ): return f"{name} is {age} years old and lives in {city} " print (create_profile(age=25 , city="Beijing" , name="Alice" ))def sum_all (*numbers ): return sum (numbers) print (sum_all(1 , 2 , 3 , 4 )) def print_info (**info ): for key, value in info.items(): print (f"{key} : {value} " ) print_info(name="Alice" , age=25 , city="Beijing" ) def complex_function (pos1, pos2, *args, default="default" , **kwargs ): print (f"位置参数: {pos1} , {pos2} " ) print (f"可变位置参数: {args} " ) print (f"默认参数: {default} " ) print (f"关键字参数: {kwargs} " ) complex_function(1 , 2 , 3 , 4 , 5 , x=10 , y=20 )
2.1.3 作用域和命名空间 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 global_var = 10 def function (): local_var = 20 print (global_var) print (local_var) counter = 0 def increment (): global counter counter += 1 return counter def outer (): x = 1 def inner (): nonlocal x x += 1 return x return inner def create_counter (): count = 0 def increment (): nonlocal count count += 1 return count return increment
2.2 高级函数特性 2.2.1 装饰器 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 def timer (func ): import time def wrapper (*args, **kwargs ): start = time.time() result = func(*args, **kwargs) end = time.time() print (f"函数 {func.__name__} 执行时间: {end - start} 秒" ) return result return wrapper @timer def slow_function (): import time time.sleep(1 ) return "完成" def repeat (times ): def decorator (func ): def wrapper (*args, **kwargs ): for _ in range (times): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(3 ) def greet (name ): print (f"Hello {name} " )
2.2.2 生成器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 def countdown (n ): while n > 0 : yield n n -= 1 for i in countdown(5 ): print (i) squares = (x**2 for x in range (10 )) def infinite_sequence (): num = 0 while True : yield num num += 1
2.3 模块和包 2.3.1 模块导入 1 2 3 4 5 6 7 8 9 10 11 12 13 14 import mathprint (math.pi)from random import randint, choiceprint (randint(1 , 10 ))import numpy as npimport pandas as pdfrom math import *
2.3.2 创建自己的模块 1 2 3 4 5 6 7 8 9 10 11 12 13 def greet (name ): return f"Hello, {name} !" PI = 3.14159 class Calculator : def add (self, x, y ): return x + y import mymoduleprint (mymodule.greet("Alice" ))
2.3.3 包的结构 1 2 3 4 5 6 7 mypackage/ __init__.py module1.py module2.py subpackage/ __init__.py module3.py
1 2 3 4 5 from .module1 import function1from .module2 import function2__all__ = ['function1' , 'function2' ]
2.3.4 常用标准库 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 from datetime import datetime, timedeltanow = datetime.now() future = now + timedelta(days=7 ) import os.pathpath = os.path.join('folder' , 'subfolder' , 'file.txt' ) import jsondata = {'name' : 'Alice' , 'age' : 25 } json_str = json.dumps(data) parsed_data = json.loads(json_str) import repattern = r'\d+' text = "abc123def456" numbers = re.findall(pattern, text) import randomrandom_num = random.randint(1 , 100 ) random_choice = random.choice(['apple' , 'banana' , 'orange' ]) import sysprint (sys.version)print (sys.platform)
第三章:面向对象编程(OOP) 3.1 类与对象基础 3.1.1 类的定义与实例化 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 class Person : species = "Human" def __init__ (self, name, age ): self .name = name self .age = age self ._private = None self .__very_private = 0 def greet (self ): return f"Hello, my name is {self.name} " def get_age_description (self ): if self .age < 18 : return "未成年" return "成年人" person1 = Person("Alice" , 25 ) person2 = Person("Bob" , 30 ) print (person1.name) print (Person.species) print (person1.greet())
3.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 28 29 30 31 32 33 34 35 class Student : def __init__ (self ): self ._score = 0 @property def score (self ): return self ._score @score.setter def score (self, value ): if not isinstance (value, int ): raise ValueError("分数必须是整数" ) if value < 0 or value > 100 : raise ValueError("分数必须在0-100之间" ) self ._score = value @property def grade (self ): if self ._score >= 90 : return 'A' elif self ._score >= 80 : return 'B' elif self ._score >= 70 : return 'C' else : return 'D' student = Student() student.score = 85 print (student.score) print (student.grade)
3.1.3 静态方法和类方法 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 class MathOperations : pi = 3.14159 def __init__ (self, value ): self .value = value def double (self ): return self .value * 2 @staticmethod def is_positive (number ): return number > 0 @classmethod def circle_area (cls, radius ): return cls.pi * radius ** 2 @classmethod def from_string (cls, string_value ): value = float (string_value) return cls(value) math_ops = MathOperations(5 ) print (math_ops.double()) print (MathOperations.is_positive(10 )) print (MathOperations.circle_area(5 )) new_ops = MathOperations.from_string("10" )
3.2 继承与多态 3.2.1 基本继承 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 class Animal : def __init__ (self, name ): self .name = name def speak (self ): raise NotImplementedError("子类必须实现这个方法" ) def introduce (self ): return f"I am {self.name} , and I can {self.speak()} " class Dog (Animal ): def speak (self ): return "woof!" def introduce (self ): base_intro = super ().introduce() return f"{base_intro} I'm a good boy!" class Cat (Animal ): def speak (self ): return "meow!" dog = Dog("Buddy" ) cat = Cat("Whiskers" ) print (dog.introduce())print (cat.introduce())
3.2.2 多重继承 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class Flyable : def fly (self ): return "I can fly!" class Swimmable : def swim (self ): return "I can swim!" class Duck (Animal, Flyable, Swimmable): def speak (self ): return "quack!" def introduce (self ): return f"{super ().introduce()} {self.fly()} {self.swim()} " duck = Duck("Donald" ) print (duck.introduce())print (Duck.__mro__)
3.2.3 抽象基类 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 from abc import ABC, abstractmethodclass Shape (ABC ): @abstractmethod def area (self ): pass @abstractmethod def perimeter (self ): pass class Rectangle (Shape ): def __init__ (self, width, height ): self .width = width self .height = height def area (self ): return self .width * self .height def perimeter (self ): return 2 * (self .width + self .height) class Circle (Shape ): def __init__ (self, radius ): self .radius = radius def area (self ): return 3.14159 * self .radius ** 2 def perimeter (self ): return 2 * 3.14159 * self .radius
3.3 魔术方法 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 class Vector : def __init__ (self, x, y ): self .x = x self .y = y def __str__ (self ): return f"Vector({self.x} , {self.y} )" def __repr__ (self ): return f"Vector(x={self.x} , y={self.y} )" def __add__ (self, other ): return Vector(self .x + other.x, self .y + other.y) def __sub__ (self, other ): return Vector(self .x - other.x, self .y - other.y) def __eq__ (self, other ): return self .x == other.x and self .y == other.y def __len__ (self ): return int ((self .x ** 2 + self .y ** 2 ) ** 0.5 ) def __call__ (self, scale ): return Vector(self .x * scale, self .y * scale) v1 = Vector(1 , 2 ) v2 = Vector(3 , 4 ) print (v1 + v2) print (v1 == v2) print (len (v1)) print (v1(2 ))
3.4 设计模式示例 3.4.1 单例模式 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 class Singleton : _instance = None def __new__ (cls ): if cls._instance is None : cls._instance = super ().__new__(cls) return cls._instance def __init__ (self ): if not hasattr (self , 'initialized' ): self .initialized = True self .data = [] s1 = Singleton() s2 = Singleton() print (s1 is s2)
3.4.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 class Animal : def speak (self ): pass class Dog (Animal ): def speak (self ): return "Woof!" class Cat (Animal ): def speak (self ): return "Meow!" class AnimalFactory : @staticmethod def create_animal (animal_type ): if animal_type.lower() == "dog" : return Dog() elif animal_type.lower() == "cat" : return Cat() else : raise ValueError("Unknown animal type" ) factory = AnimalFactory() dog = factory.create_animal("dog" ) cat = factory.create_animal("cat" )
第四章:文件操作与异常处理 4.1 文件操作 4.1.1 基本文件操作 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 with open ('example.txt' , 'r' , encoding='utf-8' ) as file: content = file.read() file.seek(0 ) chunk = file.read(10 ) file.seek(0 ) line = file.readline() file.seek(0 ) lines = file.readlines() file.seek(0 ) for line in file: print (line.strip()) with open ('output.txt' , 'w' , encoding='utf-8' ) as file: file.write('Hello, World!\n' ) lines = ['Line 1\n' , 'Line 2\n' , 'Line 3\n' ] file.writelines(lines) with open ('log.txt' , 'a' , encoding='utf-8' ) as file: file.write('New log entry\n' )
4.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 28 29 import osimport shutilcurrent_dir = os.getcwd() file_path = os.path.join('folder' , 'subfolder' , 'file.txt' ) abs_path = os.path.abspath(file_path) dir_name = os.path.dirname(file_path) base_name = os.path.basename(file_path) os.makedirs('new_folder' , exist_ok=True ) os.rename('old.txt' , 'new.txt' ) os.remove('file.txt' ) shutil.copy('source.txt' , 'dest.txt' ) shutil.move('source.txt' , 'new_location' ) file_exists = os.path.exists('file.txt' ) is_file = os.path.isfile('file.txt' ) is_dir = os.path.isdir('folder' ) file_size = os.path.getsize('file.txt' ) file_stats = os.stat('file.txt' ) for root, dirs, files in os.walk('folder' ): print (f'当前目录: {root} ' ) print (f'子目录: {dirs} ' ) print (f'文件: {files} ' )
4.1.3 二进制文件操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 with open ('image.jpg' , 'rb' ) as file: binary_data = file.read() with open ('copy.jpg' , 'wb' ) as file: file.write(binary_data) import structdata = struct.pack('iif' , 1 , 2 , 3.14 ) numbers = struct.unpack('iif' , data)
4.2 异常处理 4.2.1 基本异常处理 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 try : x = int (input ("请输入一个数字: " )) result = 10 / x except ValueError: print ("输入必须是数字" ) except ZeroDivisionError: print ("不能除以零" ) except Exception as e: print (f"发生错误: {e} " ) else : print (f"结果是: {result} " ) finally : print ("这总是会执行" ) try : pass except (ValueError, TypeError) as e: print (f"发生了值错误或类型错误: {e} " )
4.2.2 自定义异常 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 class CustomError (Exception ): def __init__ (self, message, error_code ): super ().__init__(message) self .error_code = error_code def process_age (age ): if age < 0 : raise CustomError("年龄不能为负数" , 1001 ) if age > 150 : raise CustomError("年龄超出正常范围" , 1002 ) return age try : age = process_age(-5 ) except CustomError as e: print (f"错误 {e.error_code} : {str (e)} " )
4.2.3 上下文管理器 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 class FileManager : def __init__ (self, filename, mode ): self .filename = filename self .mode = mode self .file = None def __enter__ (self ): self .file = open (self .filename, self .mode) return self .file def __exit__ (self, exc_type, exc_val, exc_tb ): if self .file: self .file.close() return False with FileManager('test.txt' , 'w' ) as file: file.write('Hello, World!' ) from contextlib import contextmanager@contextmanager def timer (): import time start = time.time() yield end = time.time() print (f"执行时间: {end - start} 秒" ) with timer(): import time time.sleep(1 )
4.2.4 调试和日志 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 import logginglogging.basicConfig( level=logging.DEBUG, format ='%(asctime)s - %(name)s - %(levelname)s - %(message)s' , filename='app.log' ) logger = logging.getLogger(__name__) try : logger.debug("调试信息" ) logger.info("普通信息" ) logger.warning("警告信息" ) result = 1 / 0 except Exception as e: logger.error("发生错误" , exc_info=True ) logger.critical("严重错误" ) def calculate_square_root (n ): assert n >= 0 , "输入必须是非负数" return n ** 0.5
第五章:高级Python特性 5.1 迭代器和生成器 5.1.1 迭代器 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 class CountDown : def __init__ (self, start ): self .start = start def __iter__ (self ): return self def __next__ (self ): if self .start <= 0 : raise StopIteration self .start -= 1 return self .start + 1 counter = CountDown(5 ) for num in counter: print (num) class Range : def __init__ (self, start, end ): self .start = start self .end = end def __iter__ (self ): current = self .start while current < self .end: yield current current += 1 for i in Range(1 , 5 ): print (i)
5.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 28 29 30 31 32 33 def fibonacci (): a, b = 0 , 1 while True : yield a a, b = b, a + b fib = fibonacci() for _ in range (10 ): print (next (fib)) squares = (x**2 for x in range (10 )) print (list (squares)) def numbers (): for i in range (1 , 11 ): yield i def squares (numbers ): for n in numbers: yield n**2 def evens (numbers ): for n in numbers: if n % 2 == 0 : yield n pipeline = evens(squares(numbers())) print (list (pipeline))
5.2 装饰器进阶 5.2.1 带参数的装饰器 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 def repeat (times ): def decorator (func ): def wrapper (*args, **kwargs ): for _ in range (times): result = func(*args, **kwargs) return result return wrapper return decorator @repeat(3 ) def greet (name ): print (f"Hello {name} " ) class Trace : def __init__ (self, handle_result=False ): self .handle_result = handle_result def __call__ (self, func ): def wrapper (*args, **kwargs ): print (f"Calling {func.__name__} " ) result = func(*args, **kwargs) if self .handle_result: print (f"Result: {result} " ) return result return wrapper @Trace(handle_result=True ) def add (a, b ): return a + b
5.2.2 多重装饰器 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 def bold (func ): def wrapper (): return f"<b>{func()} </b>" return wrapper def italic (func ): def wrapper (): return f"<i>{func()} </i>" return wrapper @bold @italic def hello (): return "Hello, World!" print (hello())
5.3 元类和类装饰器 5.3.1 元类 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 class SingletonMeta (type ): _instances = {} def __call__ (cls, *args, **kwargs ): if cls not in cls._instances: cls._instances[cls] = super ().__call__(*args, **kwargs) return cls._instances[cls] class Database (metaclass=SingletonMeta): def __init__ (self ): self .connected = False def connect (self ): self .connected = True db1 = Database() db2 = Database() print (db1 is db2) class ValidateMeta (type ): def __new__ (cls, name, bases, attrs ): for key, value in attrs.items(): if isinstance (value, property ): attrs[f'_validate_{key} ' ] = cls.create_validator(key) return super ().__new__(cls, name, bases, attrs) @staticmethod def create_validator (name ): def validator (self, value ): if value < 0 : raise ValueError(f"{name} must be positive" ) return value return validator
5.3.2 描述符 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 class Positive : def __init__ (self ): self ._value = {} def __get__ (self, instance, owner ): if instance is None : return self return self ._value.get(instance, 0 ) def __set__ (self, instance, value ): if value < 0 : raise ValueError("Value must be positive" ) self ._value[instance] = value class Point : x = Positive() y = Positive() def __init__ (self, x, y ): self .x = x self .y = y
5.4 并发编程 5.4.1 多线程 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 import threadingimport timeclass Counter : def __init__ (self ): self .value = 0 self .lock = threading.Lock() def increment (self ): with self .lock: current = self .value time.sleep(0.1 ) self .value = current + 1 counter = Counter() threads = [] for _ in range (5 ): thread = threading.Thread(target=counter.increment) threads.append(thread) thread.start() for thread in threads: thread.join() print (f"Final count: {counter.value} " )from concurrent.futures import ThreadPoolExecutordef worker (x ): return x * x with ThreadPoolExecutor(max_workers=3 ) as executor: results = executor.map (worker, range (10 )) print (list (results))
5.4.2 多进程 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 from multiprocessing import Process, Poolimport osdef worker (name ): print (f'Worker {name} : {os.getpid()} ' ) processes = [] for i in range (3 ): p = Process(target=worker, args=(i,)) processes.append(p) p.start() for p in processes: p.join() def f (x ): return x * x with Pool(5 ) as p: print (p.map (f, range (10 )))
5.4.3 异步编程 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 import asyncioasync def async_hello (name, delay ): await asyncio.sleep(delay) print (f'Hello, {name} ' ) async def main (): tasks = [ async_hello("Alice" , 2 ), async_hello("Bob" , 1 ), async_hello("Charlie" , 3 ) ] await asyncio.gather(*tasks) asyncio.run(main()) class AsyncResource : async def __aenter__ (self ): print ("获取资源" ) return self async def __aexit__ (self, exc_type, exc_val, exc_tb ): print ("释放资源" ) async def use_resource (): async with AsyncResource() as res: print ("使用资源" )
第六章:常用标准库 6.1 文本处理 6.1.1 string 模块 1 2 3 4 5 6 7 8 9 10 11 12 import stringprint (string.ascii_letters) print (string.digits) print (string.punctuation) print (string.whitespace) template = string.Template('Hello, $name! You have $amount dollars.' ) result = template.substitute(name='Alice' , amount=100 ) print (result)
6.1.2 re 模块(正则表达式) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import retext = "My email is [email protected] and phone is 123-456-7890" email_pattern = r'\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b' phone_pattern = r'\d{3}-\d{3}-\d{4}' emails = re.findall(email_pattern, text) phones = re.findall(phone_pattern, text) new_text = re.sub(phone_pattern, '***-***-****' , text) words = re.split(r'\W+' , text) email_regex = re.compile (email_pattern) matches = email_regex.finditer(text) for match in matches: print (f"Found email at position {match .start()} : {match .group()} " )
6.2 日期和时间 6.2.1 datetime 模块 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 from datetime import datetime, date, time, timedeltaimport pytz now = datetime.now() today = date.today() specific_date = date(2023 , 12 , 31 ) specific_time = time(13 , 30 , 0 ) specific_datetime = datetime(2023 , 12 , 31 , 13 , 30 , 0 ) formatted = now.strftime("%Y-%m-%d %H:%M:%S" ) parsed = datetime.strptime("2023-12-31 13:30:00" , "%Y-%m-%d %H:%M:%S" ) tomorrow = today + timedelta(days=1 ) next_week = today + timedelta(weeks=1 ) two_hours_later = now + timedelta(hours=2 ) utc = pytz.UTC pacific = pytz.timezone('US/Pacific' ) utc_time = datetime.now(utc) pacific_time = utc_time.astimezone(pacific)
6.3 数据处理 6.3.1 json 模块 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 import jsondata = { 'name' : 'Alice' , 'age' : 30 , 'cities' : ['New York' , 'London' ], 'active' : True , 'height' : 1.75 } json_str = json.dumps(data, indent=4 ) print (json_str)with open ('data.json' , 'w' ) as f: json.dump(data, f, indent=4 ) parsed_data = json.loads(json_str) with open ('data.json' , 'r' ) as f: loaded_data = json.load(f) class Person : def __init__ (self, name, age ): self .name = name self .age = age def person_encoder (obj ): if isinstance (obj, Person): return {'name' : obj.name, 'age' : obj.age} raise TypeError(f'Object of type {type (obj)} is not JSON serializable' ) person = Person('Bob' , 25 ) json_str = json.dumps(person, default=person_encoder)
6.3.2 csv 模块 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 import csvdata = [ ['Name' , 'Age' , 'City' ], ['Alice' , 25 , 'New York' ], ['Bob' , 30 , 'London' ] ] with open ('data.csv' , 'w' , newline='' ) as f: writer = csv.writer(f) writer.writerows(data) dict_data = [ {'name' : 'Alice' , 'age' : 25 , 'city' : 'New York' }, {'name' : 'Bob' , 'age' : 30 , 'city' : 'London' } ] with open ('dict_data.csv' , 'w' , newline='' ) as f: fieldnames = ['name' , 'age' , 'city' ] writer = csv.DictWriter(f, fieldnames=fieldnames) writer.writeheader() writer.writerows(dict_data) with open ('data.csv' , 'r' ) as f: reader = csv.reader(f) for row in reader: print (row) with open ('dict_data.csv' , 'r' ) as f: reader = csv.DictReader(f) for row in reader: print (row['name' ], row['age' ])
6.4 系统和OS操作 6.4.1 os 和 sys 模块 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 import osimport sysimport platformprint (sys.platform) print (sys.version) print (platform.system()) print (os.name) print (os.environ.get('PATH' ))os.environ['MY_VAR' ] = 'value' current_dir = os.getcwd() os.chdir('..' ) path = os.path.join('folder' , 'subfolder' , 'file.txt' ) abs_path = os.path.abspath(path) norm_path = os.path.normpath(path) os.makedirs('new/nested/directory' , exist_ok=True ) os.removedirs('new/nested/directory' ) for root, dirs, files in os.walk('.' ): print (f"当前目录: {root} " ) print (f"子目录: {dirs} " ) print (f"文件: {files} " ) pid = os.getpid() os.system('echo Hello' )
6.4.2 argparse 模块 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import argparsedef main (): parser = argparse.ArgumentParser(description='示例命令行程序' ) parser.add_argument('name' , help ='用户名' ) parser.add_argument('-a' , '--age' , type =int , help ='年龄' ) parser.add_argument('-v' , '--verbose' , action='store_true' , help ='显示详细信息' ) args = parser.parse_args() print (f"Hello, {args.name} " ) if args.age: print (f"You are {args.age} years old" ) if args.verbose: print ("Verbose mode enabled" ) if __name__ == '__main__' : main()
6.4.3 logging 模块 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 import logginglogging.basicConfig( level=logging.DEBUG, format ='%(asctime)s - %(name)s - %(levelname)s - %(message)s' , filename='app.log' , filemode='w' ) logger = logging.getLogger(__name__) console_handler = logging.StreamHandler() console_handler.setLevel(logging.INFO) file_handler = logging.FileHandler('error.log' ) file_handler.setLevel(logging.ERROR) formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s' ) console_handler.setFormatter(formatter) file_handler.setFormatter(formatter) logger.addHandler(console_handler) logger.addHandler(file_handler) logger.debug('调试信息' ) logger.info('一般信息' ) logger.warning('警告信息' ) logger.error('错误信息' ) logger.critical('严重错误' )
第七章:算法与数据结构 7.1 基本数据结构实现 7.1.1 链表 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 55 56 class Node : def __init__ (self, data ): self .data = data self .next = None class LinkedList : def __init__ (self ): self .head = None def append (self, data ): new_node = Node(data) if not self .head: self .head = new_node return current = self .head while current.next : current = current.next current.next = new_node def prepend (self, data ): new_node = Node(data) new_node.next = self .head self .head = new_node def delete (self, data ): if not self .head: return if self .head.data == data: self .head = self .head.next return current = self .head while current.next : if current.next .data == data: current.next = current.next .next return current = current.next def display (self ): elements = [] current = self .head while current: elements.append(current.data) current = current.next return elements ll = LinkedList() ll.append(1 ) ll.append(2 ) ll.prepend(0 ) print (ll.display()) ll.delete(1 ) print (ll.display())
7.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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 class Stack : def __init__ (self ): self .items = [] def push (self, item ): self .items.append(item) def pop (self ): if not self .is_empty(): return self .items.pop() raise IndexError("Stack is empty" ) def peek (self ): if not self .is_empty(): return self .items[-1 ] raise IndexError("Stack is empty" ) def is_empty (self ): return len (self .items) == 0 def size (self ): return len (self .items) from collections import dequeclass Queue : def __init__ (self ): self .items = deque() def enqueue (self, item ): self .items.append(item) def dequeue (self ): if not self .is_empty(): return self .items.popleft() raise IndexError("Queue is empty" ) def front (self ): if not self .is_empty(): return self .items[0 ] raise IndexError("Queue is empty" ) def is_empty (self ): return len (self .items) == 0 def size (self ): return len (self .items)
7.1.3 二叉树 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 55 56 57 58 59 60 61 62 63 class TreeNode : def __init__ (self, data ): self .data = data self .left = None self .right = None class BinaryTree : def __init__ (self ): self .root = None def insert (self, data ): if not self .root: self .root = TreeNode(data) else : self ._insert_recursive(self .root, data) def _insert_recursive (self, node, data ): if data < node.data: if node.left is None : node.left = TreeNode(data) else : self ._insert_recursive(node.left, data) else : if node.right is None : node.right = TreeNode(data) else : self ._insert_recursive(node.right, data) def inorder (self ): elements = [] self ._inorder_recursive(self .root, elements) return elements def _inorder_recursive (self, node, elements ): if node: self ._inorder_recursive(node.left, elements) elements.append(node.data) self ._inorder_recursive(node.right, elements) def preorder (self ): elements = [] self ._preorder_recursive(self .root, elements) return elements def _preorder_recursive (self, node, elements ): if node: elements.append(node.data) self ._preorder_recursive(node.left, elements) self ._preorder_recursive(node.right, elements) def postorder (self ): elements = [] self ._postorder_recursive(self .root, elements) return elements def _postorder_recursive (self, node, elements ): if node: self ._postorder_recursive(node.left, elements) self ._postorder_recursive(node.right, elements) elements.append(node.data)
7.2 排序算法 7.2.1 基本排序算法 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 def bubble_sort (arr ): n = len (arr) for i in range (n): for j in range (0 , n-i-1 ): if arr[j] > arr[j+1 ]: arr[j], arr[j+1 ] = arr[j+1 ], arr[j] return arr def selection_sort (arr ): n = len (arr) for i in range (n): min_idx = i for j in range (i+1 , n): if arr[j] < arr[min_idx]: min_idx = j arr[i], arr[min_idx] = arr[min_idx], arr[i] return arr def insertion_sort (arr ): for i in range (1 , len (arr)): key = arr[i] j = i-1 while j >= 0 and arr[j] > key: arr[j+1 ] = arr[j] j -= 1 arr[j+1 ] = key return arr
7.2.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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 def quick_sort (arr ): if len (arr) <= 1 : return arr pivot = arr[len (arr) // 2 ] left = [x for x in arr if x < pivot] middle = [x for x in arr if x == pivot] right = [x for x in arr if x > pivot] return quick_sort(left) + middle + quick_sort(right) def merge_sort (arr ): if len (arr) <= 1 : return arr mid = len (arr) // 2 left = merge_sort(arr[:mid]) right = merge_sort(arr[mid:]) return merge(left, right) def merge (left, right ): result = [] i = j = 0 while i < len (left) and j < len (right): if left[i] <= right[j]: result.append(left[i]) i += 1 else : result.append(right[j]) j += 1 result.extend(left[i:]) result.extend(right[j:]) return result def heapify (arr, n, i ): largest = i left = 2 * i + 1 right = 2 * i + 2 if left < n and arr[left] > arr[largest]: largest = left if right < n and arr[right] > arr[largest]: largest = right if largest != i: arr[i], arr[largest] = arr[largest], arr[i] heapify(arr, n, largest) def heap_sort (arr ): n = len (arr) for i in range (n // 2 - 1 , -1 , -1 ): heapify(arr, n, i) for i in range (n-1 , 0 , -1 ): arr[0 ], arr[i] = arr[i], arr[0 ] heapify(arr, i, 0 ) return arr
7.3 搜索算法 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 def binary_search (arr, target ): left, right = 0 , len (arr) - 1 while left <= right: mid = (left + right) // 2 if arr[mid] == target: return mid elif arr[mid] < target: left = mid + 1 else : right = mid - 1 return -1 def dfs (graph, start, visited=None ): if visited is None : visited = set () visited.add(start) print (start, end=' ' ) for next_vertex in graph[start]: if next_vertex not in visited: dfs(graph, next_vertex, visited) return visited from collections import dequedef bfs (graph, start ): visited = set ([start]) queue = deque([start]) while queue: vertex = queue.popleft() print (vertex, end=' ' ) for neighbor in graph[vertex]: if neighbor not in visited: visited.add(neighbor) queue.append(neighbor) return visited
第八章:动态规划与贪心算法 8.1 动态规划基础 8.1.1 基本概念与实现方法 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 def fib_recursive (n ): if n <= 1 : return n return fib_recursive(n-1 ) + fib_recursive(n-2 ) def fib_memo (n, memo=None ): if memo is None : memo = {} if n in memo: return memo[n] if n <= 1 : return n memo[n] = fib_memo(n-1 , memo) + fib_memo(n-2 , memo) return memo[n] def fib_dp (n ): if n <= 1 : return n dp = [0 ] * (n + 1 ) dp[1 ] = 1 for i in range (2 , n + 1 ): dp[i] = dp[i-1 ] + dp[i-2 ] return dp[n] def fib_optimized (n ): if n <= 1 : return n prev2, prev1 = 0 , 1 for _ in range (2 , n + 1 ): curr = prev1 + prev2 prev2, prev1 = prev1, curr return prev1
8.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 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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 def longest_increasing_subsequence (arr ): if not arr: return 0 n = len (arr) dp = [1 ] * n for i in range (1 , n): for j in range (i): if arr[i] > arr[j]: dp[i] = max (dp[i], dp[j] + 1 ) return max (dp) def edit_distance (word1, word2 ): m, n = len (word1), len (word2) dp = [[0 ] * (n + 1 ) for _ in range (m + 1 )] for i in range (m + 1 ): dp[i][0 ] = i for j in range (n + 1 ): dp[0 ][j] = j for i in range (1 , m + 1 ): for j in range (1 , n + 1 ): if word1[i-1 ] == word2[j-1 ]: dp[i][j] = dp[i-1 ][j-1 ] else : dp[i][j] = min (dp[i-1 ][j], dp[i][j-1 ], dp[i-1 ][j-1 ]) + 1 return dp[m][n] def knapsack (weights, values, capacity ): n = len (weights) dp = [[0 ] * (capacity + 1 ) for _ in range (n + 1 )] for i in range (1 , n + 1 ): for w in range (capacity + 1 ): if weights[i-1 ] <= w: dp[i][w] = max (dp[i-1 ][w], dp[i-1 ][w-weights[i-1 ]] + values[i-1 ]) else : dp[i][w] = dp[i-1 ][w] return dp[n][capacity] def longest_common_subsequence (text1, text2 ): m, n = len (text1), len (text2) dp = [[0 ] * (n + 1 ) for _ in range (m + 1 )] for i in range (1 , m + 1 ): for j in range (1 , n + 1 ): if text1[i-1 ] == text2[j-1 ]: dp[i][j] = dp[i-1 ][j-1 ] + 1 else : dp[i][j] = max (dp[i-1 ][j], dp[i][j-1 ]) lcs = [] i, j = m, n while i > 0 and j > 0 : if text1[i-1 ] == text2[j-1 ]: lcs.append(text1[i-1 ]) i -= 1 j -= 1 elif dp[i-1 ][j] > dp[i][j-1 ]: i -= 1 else : j -= 1 return '' .join(reversed (lcs))
8.2 贪心算法 8.2.1 基本贪心问题 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 def make_change (coins, amount ): coins.sort(reverse=True ) result = [] remaining = amount for coin in coins: while remaining >= coin: result.append(coin) remaining -= coin return result if remaining == 0 else None def activity_selection (start, finish ): n = len (start) activities = sorted (zip (start, finish), key=lambda x: x[1 ]) selected = [activities[0 ]] last_finish = activities[0 ][1 ] for i in range (1 , n): if activities[i][0 ] >= last_finish: selected.append(activities[i]) last_finish = activities[i][1 ] return selected def interval_scheduling (intervals ): intervals.sort(key=lambda x: x[1 ]) selected = [intervals[0 ]] last_end = intervals[0 ][1 ] for interval in intervals[1 :]: if interval[0 ] >= last_end: selected.append(interval) last_end = interval[1 ] return selected
8.2.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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 class HuffmanNode : def __init__ (self, char, freq ): self .char = char self .freq = freq self .left = None self .right = None def build_huffman_tree (chars, freqs ): nodes = [HuffmanNode(c, f) for c, f in zip (chars, freqs)] while len (nodes) > 1 : nodes.sort(key=lambda x: x.freq) left = nodes.pop(0 ) right = nodes.pop(0 ) internal = HuffmanNode(None , left.freq + right.freq) internal.left = left internal.right = right nodes.append(internal) return nodes[0 ] def get_huffman_codes (root, code="" , codes=None ): if codes is None : codes = {} if root: if root.char: codes[root.char] = code get_huffman_codes(root.left, code + "0" , codes) get_huffman_codes(root.right, code + "1" , codes) return codes def prim_mst (graph ): n = len (graph) selected = [False ] * n selected[0 ] = True edges = [] for _ in range (n - 1 ): minimum = float ('inf' ) x = y = 0 for i in range (n): if selected[i]: for j in range (n): if not selected[j] and graph[i][j]: if graph[i][j] < minimum: minimum = graph[i][j] x, y = i, j selected[y] = True edges.append((x, y, graph[x][y])) return edges
第九章:高级算法与技巧 9.1 图论算法 9.1.1 图的表示与基本操作 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 class Graph : def __init__ (self ): self .graph = {} def add_vertex (self, vertex ): if vertex not in self .graph: self .graph[vertex] = [] def add_edge (self, v1, v2, directed=False ): if v1 not in self .graph: self .add_vertex(v1) if v2 not in self .graph: self .add_vertex(v2) self .graph[v1].append(v2) if not directed: self .graph[v2].append(v1) def get_vertices (self ): return list (self .graph.keys()) def get_edges (self ): edges = [] for vertex in self .graph: for neighbor in self .graph[vertex]: edges.append((vertex, neighbor)) return edges
9.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 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 def dijkstra (graph, start ): distances = {vertex: float ('infinity' ) for vertex in graph} distances[start] = 0 unvisited = set (graph.keys()) path = {} while unvisited: current = min (unvisited, key=lambda vertex: distances[vertex]) if distances[current] == float ('infinity' ): break for neighbor, weight in graph[current].items(): distance = distances[current] + weight if distance < distances[neighbor]: distances[neighbor] = distance path[neighbor] = current unvisited.remove(current) return distances, path def floyd_warshall (graph ): vertices = list (graph.keys()) n = len (vertices) dist = {i: {j: float ('infinity' ) for j in vertices} for i in vertices} for i in vertices: dist[i][i] = 0 for j in graph[i]: dist[i][j] = graph[i][j] for k in vertices: for i in vertices: for j in vertices: if dist[i][k] + dist[k][j] < dist[i][j]: dist[i][j] = dist[i][k] + dist[k][j] return dist
9.1.3 最小生成树算法 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 class UnionFind : def __init__ (self, vertices ): self .parent = {v: v for v in vertices} self .rank = {v: 0 for v in vertices} def find (self, item ): if self .parent[item] != item: self .parent[item] = self .find(self .parent[item]) return self .parent[item] def union (self, x, y ): xroot, yroot = self .find(x), self .find(y) if xroot == yroot: return if self .rank[xroot] < self .rank[yroot]: self .parent[xroot] = yroot elif self .rank[xroot] > self .rank[yroot]: self .parent[yroot] = xroot else : self .parent[yroot] = xroot self .rank[xroot] += 1 def kruskal (graph ): edges = [] for u in graph: for v, weight in graph[u].items(): edges.append((weight, u, v)) edges.sort() vertices = list (graph.keys()) uf = UnionFind(vertices) mst = [] for weight, u, v in edges: if uf.find(u) != uf.find(v): uf.union(u, v) mst.append((u, v, weight)) return mst
9.2 高级数据结构 9.2.1 平衡二叉树(AVL树) 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 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 class AVLNode : def __init__ (self, key ): self .key = key self .left = None self .right = None self .height = 1 class AVLTree : def get_height (self, node ): if not node: return 0 return node.height def get_balance (self, node ): if not node: return 0 return self .get_height(node.left) - self .get_height(node.right) def right_rotate (self, y ): x = y.left T2 = x.right x.right = y y.left = T2 y.height = max (self .get_height(y.left), self .get_height(y.right)) + 1 x.height = max (self .get_height(x.left), self .get_height(x.right)) + 1 return x def left_rotate (self, x ): y = x.right T2 = y.left y.left = x x.right = T2 x.height = max (self .get_height(x.left), self .get_height(x.right)) + 1 y.height = max (self .get_height(y.left), self .get_height(y.right)) + 1 return y def insert (self, root, key ): if not root: return AVLNode(key) if key < root.key: root.left = self .insert(root.left, key) elif key > root.key: root.right = self .insert(root.right, key) else : return root root.height = max (self .get_height(root.left), self .get_height(root.right)) + 1 balance = self .get_balance(root) if balance > 1 and key < root.left.key: return self .right_rotate(root) if balance < -1 and key > root.right.key: return self .left_rotate(root) if balance > 1 and key > root.left.key: root.left = self .left_rotate(root.left) return self .right_rotate(root) if balance < -1 and key < root.right.key: root.right = self .right_rotate(root.right) return self .left_rotate(root) return root
9.2.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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 class Color : RED = True BLACK = False class RBNode : def __init__ (self, key ): self .key = key self .left = None self .right = None self .parent = None self .color = Color.RED class RedBlackTree : def __init__ (self ): self .NIL = RBNode(None ) self .NIL.color = Color.BLACK self .root = self .NIL def left_rotate (self, x ): y = x.right x.right = y.left if y.left != self .NIL: y.left.parent = x y.parent = x.parent if x.parent == None : self .root = y elif x == x.parent.left: x.parent.left = y else : x.parent.right = y y.left = x x.parent = y def right_rotate (self, x ): y = x.left x.left = y.right if y.right != self .NIL: y.right.parent = x y.parent = x.parent if x.parent == None : self .root = y elif x == x.parent.right: x.parent.right = y else : x.parent.left = y y.right = x x.parent = y def insert (self, key ): node = RBNode(key) node.left = self .NIL node.right = self .NIL y = None x = self .root while x != self .NIL: y = x if node.key < x.key: x = x.left else : x = x.right node.parent = y if y == None : self .root = node elif node.key < y.key: y.left = node else : y.right = node self .fix_insert(node) def fix_insert (self, k ): while k.parent and k.parent.color == Color.RED: if k.parent == k.parent.parent.right: u = k.parent.parent.left if u.color == Color.RED: u.color = Color.BLACK k.parent.color = Color.BLACK k.parent.parent.color = Color.RED k = k.parent.parent else : if k == k.parent.left: k = k.parent self .right_rotate(k) k.parent.color = Color.BLACK k.parent.parent.color = Color.RED self .left_rotate(k.parent.parent) else : u = k.parent.parent.right if u.color == Color.RED: u.color = Color.BLACK k.parent.color = Color.BLACK k.parent.parent.color = Color.RED k = k.parent.parent else : if k == k.parent.right: k = k.parent self .left_rotate(k) k.parent.color = Color.BLACK k.parent.parent.color = Color.RED self .right_rotate(k.parent.parent) if k == self .root: break self .root.color = Color.BLACK
Sponser/打赏!点这里!如果你觉得这对你有帮助或想要施舍下这个小可怜的话 (〃` 3′〃)
微信赞赏码
Only Accept USDT-TRON(TRC20) !!
Only Accept USDT-Optimism !!
Only Accept USDT-Polygon !!