Python 枚举与排序

部署运行你感兴趣的模型镜像

一、枚举(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、希尔排序

  • 思想:插入排序的“分组-缩小步长”版。
  • 时间复杂度:取决于增量序列,平均O(nlog_2n)~O(n^2)
  • 稳定性:不稳定。
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]

您可能感兴趣的与本文相关的镜像

Python3.8

Python3.8

Conda
Python

Python 是一种高级、解释型、通用的编程语言,以其简洁易读的语法而闻名,适用于广泛的应用,包括Web开发、数据分析、人工智能和自动化脚本

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值