一、枚举(Enum)
1、enumerate()函数(遍历时的枚举)
这是Python内置的一个函数,用于在遍历可迭代对象时同时获取元素的索引和值。
fruits = ['apple', 'banana', 'cherry']
for index, fruit in enumerate(fruits): #可写为enumerate(fruits,start=1),索引从1开始
print(f"索引 {index} 对应的水果是 {fruit}")
# 索引 0 对应的水果是 apple
# 索引 1 对应的水果是 banana
# 索引 2 对应的水果是 cherry
特点:
- 返回一个枚举对象(可迭代的)
- 默认从0开始计数,但可以通过
start参数指定起始值 - 常用于需要同时访问索引和值的循环场景
2、enum模块(枚举类型)
这是Python标准库中的一个模块,用于创建具有命名常量的枚举类型。
from enum import Enum, auto
class Color(Enum):
RED = 1
GREEN = 2
BLUE = auto() # auto() 会自动递增 =3
print(Color.RED) # Color.RED
print(Color.BLUE.value) # 3
print(Color.RED.name) # 'RED'
for color in Color:
print(color)
# 输出:
# Color.RED
# Color.GREEN
# Color.BLUE
特点:
- 创建有意义的符号名称而不是使用幻数(魔法数字:直接硬编码在源码里、没有语义解释的任何数字(或字符串)常量。)
- 值是不可变的
- 支持迭代和比较(如:Color.RED==Color.RED or Color.RED is Color.RED)
- 提供更好的代码可读性和维护性
二、排序(Sorting)
Python提供了多种排序方式,主要使用sorted()函数和列表的sort()方法。
1、使用sorted()函数,返回一个新的已排序列表,不改变原列表。
numbers = [3, 1, 4, 1, 5, 9, 2]
sorted_numbers = sorted(numbers)
print(sorted_numbers) # [1, 1, 2, 3, 4, 5, 9]
print(numbers) # [3, 1, 4, 1, 5, 9, 2] (原列表未改变)
# 降序
numbers = [3, 1, 4, 1, 5, 9, 2]
sorted_numbers = sorted(numbers, reverse=True)
print(sorted_numbers) # [9, 5, 4, 3, 2, 1, 1]
2、使用sort()方法,直接修改原列表
numbers = [3, 1, 4, 1, 5, 9, 2]
numbers.sort() # 输入reverse=True为降序
print(numbers) # [1, 1, 2, 3, 4, 5, 9]
3、自定义排序键,使用key参数指定排序依据
words = ['banana', 'pie', 'apple', 'Washington']
sorted_words = sorted(words, key=len) # 按长度排序
print(sorted_words) # ['pie', 'apple', 'banana', 'Washington']
4、复杂对象排序
students = [
{'name': 'Alice', 'age': 20},
{'name': 'Bob', 'age': 18},
{'name': 'Charlie', 'age': 22}
]
# 按年龄排序
sorted_students = sorted(students, key=lambda x: x['age'])
print(sorted_students)
# 输出:
# [{'name': 'Bob', 'age': 18}, {'name': 'Alice', 'age': 20}, {'name': 'Charlie', 'age':22}]
5、多级排序
# 先按年龄,再按姓名排序
students = [
{'name': 'Alice', 'age': 20},
{'name': 'Bob', 'age': 18},
{'name': 'Charlie', 'age': 18}
]
sorted_students = sorted(students, key=lambda x: (x['age'], x['name']))
print(sorted_students)
# 输出:
# [{'name': 'Bob', 'age': 18}, {'name': 'Charlie', 'age': 18}, {'name': 'Alice', 'age': 20}]
三、十大排序算法
1、冒泡排序
- 核心思想:相邻两两比较,把最大/最小“冒”到端点。
- 时间复杂度:最好O(n)(已有序),最坏O(n²)(逆序),平均O(n²)。
- 稳定性:稳定。
a = [5, 2, 9, 1, 5, 6, 3]
print("原始:", a)
def bubble_sort(arr):
for i in range(len(arr)-1):
swapped = False
for j in range(len(arr)-1-i):
if arr[j] > arr[j+1]:
arr[j], arr[j+1] = arr[j+1], arr[j]
swapped = True
if not swapped: break
return arr
print("冒泡:", bubble_sort(a)) #输出:[1, 2, 3, 5, 5, 6, 9]
2、选择排序
- 思想:每轮选最小,放到已排区间末尾。
- 时间复杂度:始终O(n²)。
- 稳定性:不稳定(可能改变相同元素的顺序)。
a = [5, 2, 9, 1, 5, 6, 3]
print("原始:", a)
def selection_sort(arr):
for i in range(len(arr)-1):
min_idx = i
for j in range(i+1, len(arr)):
if arr[j] < arr[min_idx]:
min_idx = j
arr[i], arr[min_idx] = arr[min_idx], arr[i]
return arr
print("选择:", selection_sort(a)) #输出:[1, 2, 3, 5, 5, 6, 9]
# 但该排序算法不稳定,可能改变相同元素的顺序。
# 例:
# 若将items = [(2, 'B'), (2, 'A'), (1, 'C')]目标是按第一个元素升序排序
# 稳定排序应保持 (2, 'B') 在 (2, 'A') 前面
# 但选择排序,会找到最小值是 (1, 'C'),和第一个元素 (2, 'B') 交换:
# 得到[(1, 'C'), (2, 'A'), (2, 'B')]
# 原本 (2, 'B') 在 (2, 'A') 前面,现在变成 (2, 'A') 在 (2, 'B') 前面了。
3、插入排序
- 思想:把未排元素插入到左侧已排区间。
- 时间复杂度:最好O(n)(已有序),最坏O(n²)(逆序),平均O(n²)。
- 稳定性:稳定。
a = [5, 2, 9, 1, 5, 6, 3]
print("原始:", a)
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
print("插入排序:", insertion_sort(a)) #输出:[1, 2, 3, 5, 5, 6, 9]
4、希尔排序
- 思想:插入排序的“分组-缩小步长”版。
- 时间复杂度:取决于增量序列,平均
。
- 稳定性:不稳定。
a = [5, 2, 9, 1, 5, 6, 3]
print("原始:", a)
def shell_sort(arr):
gap = len(arr) // 2
while gap > 0:
for i in range(gap, len(arr)):
temp = arr[i]
j = i
while j >= gap and arr[j-gap] > temp:
arr[j] = arr[j-gap]
j -= gap
arr[j] = temp
gap //= 2
return arr
print("希尔排序:", shell_sort(a)) #输出:[1, 2, 3, 5, 5, 6, 9]
5、归并排序
- 思想:分治法,递归拆分数组后合并有序子序列。
- 时间复杂度:始终O(n log n)。
- 稳定性:稳定。
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
6、快速排序
- 思想:分治:先分两半,再合并有序段。
- 时间复杂度:最好O(n log n),最坏O(n²)(不平衡分区),平均O(n log n)。
- 稳定性:不稳定。
a = [5, 2, 9, 1, 5, 6, 3]
print("原始:", a)
def quick_sort(arr):
if len(arr) <= 1: return arr
pivot = arr[0]
left = [x for x in arr[1:] if x < pivot] #改变改行与下一行比较符号可变为升序
right = [x for x in arr[1:] if x >= pivot]
return quick_sort(left) + [pivot] + quick_sort(right)
print("快速排序:", quick_sort(a)) #输出:[1, 2, 3, 5, 5, 6, 9]
7、堆排序
- 思想:建最大/最小堆,逐次弹出堆顶。
- 时间复杂度:始终O(n log n)。
- 稳定性:不稳定。
a = [5, 2, 9, 1, 5, 6, 3]
print("原始:", a)
def heap_sort(arr):
def heapify(arr, n, i):
largest = i
l, r = 2 * i + 1, 2 * i + 2
if l < n and arr[l] > arr[largest]: largest = l
if r < n and arr[r] > arr[largest]: largest = r
if largest != i:
arr[i], arr[largest] = arr[largest], arr[i]
heapify(arr, n, largest)
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
print("堆排序:", heap_sort(a)) #输出:[1, 2, 3, 5, 5, 6, 9]
8、计数排序
- 思想:统计元素出现次数,按计数重建有序序列。
- 时间复杂度:O(n + k)(k为数据范围)。
- 稳定性:稳定(需反向填充)。
a = [5, 2, 9, 1, 5, 6, 3]
print("原始:", a)
def counting_sort(arr, max_val):
bucket = [0] * (max_val + 1)
for num in arr: bucket[num] += 1
idx = 0
for i in range(len(bucket)):
k = i
# k=max_val-i # ,降序
while bucket[k] > 0:
arr[idx] = k
idx += 1
bucket[k] -= 1
return arr
print("计数排序:", counting_sort(a, 9)) # 输出:[1, 2, 3, 5, 5, 6, 9]
9、桶排序
- 思想:将数据分到有限数量的桶中,对每个桶单独排序后合并。
- 时间复杂度:平均O(n + k),最坏O(n²)(数据集中在一个桶)。
- 稳定性:取决于桶内排序算法。
a = [5, 2, 9, 1, 5, 6, 3]
print("原始:", a)
def bucket_sort(arr, bucket_size=5):
min_val, max_val = min(arr), max(arr)
bucket_count = (max_val - min_val) // bucket_size + 1
buckets = [[] for _ in range(bucket_count)]
for num in arr:
buckets[(num - min_val) // bucket_size].append(num)
arr.clear()
for bucket in buckets:
arr.extend(sorted(bucket))
return arr
print("桶排序:", bucket_sort(a, 3)) # 输出:[1, 2, 3, 5, 5, 6, 9]
10、基数排序
- 思想:按位数从低位到高位依次排序(通常用计数排序作为子算法)。
- 时间复杂度:O(n × k)(k为最大位数)。
- 稳定性:稳定。
a = [5, 2, 9, 1, 5, 6, 3]
print("原始:", a)
def radix_sort(arr):
max_val = max(arr)
exp = 1
while max_val // exp > 0:
counting_sort_by_digit(arr, exp)
exp *= 10
return arr
def counting_sort_by_digit(arr, exp):
output = [0] * len(arr)
count = [0] * 10
for num in arr:
digit = (num // exp) % 10
count[digit] += 1
for i in range(1, 10):
count[i] += count[i-1]
for num in reversed(arr):
digit = (num // exp) % 10
output[count[digit]-1] = num
count[digit] -= 1
for i in range(len(arr)):
arr[i] = output[i]
print("基数排序:", radix_sort(a)) # 输出:[1, 2, 3, 5, 5, 6, 9]
2520

被折叠的 条评论
为什么被折叠?



