我仅仅用一段提示词学会了python所有竞赛语法🚀🚀🚀

355 阅读21分钟

提示词

我最近正在准备python组算法竞赛,由于我之前是 c++选手 , 对于python的一些算法竞赛常用的语法和工具不是很熟悉,你现在充当我的竞赛导师,指导我学习python用于算法竞赛的知识。

包括但不仅限于以下问题的作答:

1.最基本的数字,字符串,字符等的输入输出,还有字符串,数字的一些操作等等,特别例如多个数字,字符的读取(输入之间有空格)等等。

2.常用数据结构的操控(每一种的增删改查,排序,反转等等),此外对于py数组,你需要重点讲解每一个部分。尤其是算法竞赛常用的 , 比如优先队列 ,等等

3.py一些语法特性例如语法糖等等,有很多不要仅提供语法糖的介绍。

4.自带的算法库,例如排序等等,注意,不要仅提供排序的介绍 , 需要有多重排序方式 , 比如升降序 , 自定义排序 ;

注意:

1.注意须要保证全面且易懂,且非常详细,复杂的地方标注注释。不用担心篇幅不够,有多少写多少。

2.对于每一个知识点,给出不下于15个的案例,每个案例都包含不同的知识,就是不重复,并且配有详细的注释和说明。

3.针对算法竞赛,python一些独有的技巧你要给出介绍,另外Python比较由于其他语言的功能或语法工具等的优势你要提一下(例如整形不会溢出)。

5.上述我所要求的内容只是给你一个说明,只是告诉你你应该写哪些内容,但远远不仅仅只是这些,你需要考虑和扩展更多。

6.蓝桥杯官方要求的是只能使用Python3.8版本,且只能使用Python自带的库与语法等等,也就是你从官网安装的原生的Python,你给的示例里不应该包含其他库,例如需要pip或者conda安装的库。

关于你的作答:

1.你的制造者限制了你一次回答的最大输出字符量,我不知道你是否知道这件事情,他们应该没有告诉你,这样的话在一次性的对话里你肯定无法将所有的内容展现出来。但是现在你知道了,所以不用担心字数,尽可能多的写,如果你的输出出现中断我会说继续,这样你就接着写。

2.如果你的输出出现了中断,且正好在代码块里出现中断,那么接下来回答的时候注意在开头加上```

3.请注意格式,标题,序号等等。

Python 算法竞赛指南

一、基本输入输出与字符串、数字操作

1.1 基本输入输出

Python 中的 input() 函数用于获取用户输入,print() 函数用于输出。对于算法竞赛来说,掌握如何快速读取和处理数据是非常重要的。

  • 单个值的输入输出
# 输入一个整数并输出
n = int(input())
print(n)

# 输入一个浮点数并输出
f = float(input())
print(f)

# 输入一个字符串并输出
s = input()
print(s)
  • 多个值的输入(以空格分隔)
# 输入一行包含多个整数,并将它们转换为列表
nums = list(map(int, input().split()))
print(nums)

# 输入一行包含多个浮点数,并将它们转换为列表
floats = list(map(float, input().split()))
print(floats)

# 输入一行包含多个字符串,并将它们转换为列表
words = input().split()
print(words)
  • 多行输入
# 输入 n 行,每行一个整数
n = int(input())
numbers = [int(input()) for _ in range(n)]
print(numbers)

# 输入 n 行,每行多个整数
n = int(input())
matrix = [list(map(int, input().split())) for _ in range(n)]
print(matrix)

1.2 字符串操作

字符串是算法竞赛中常见的数据类型之一,了解其常用操作可以提高解题效率。

  • 字符串拼接
# 使用 + 拼接字符串
s1 = "Hello"
s2 = "World"
result = s1 + " " + s2
print(result)  # 输出: Hello World

# 使用 join() 方法拼接字符串列表
words = ["Hello", "World"]
result = " ".join(words)
print(result)  # 输出: Hello World
  • 字符串切片
# 获取字符串的子串
s = "HelloWorld"
print(s[0:5])   # 输出: Hello
print(s[5:])    # 输出: World
print(s[:5])    # 输出: Hello
print(s[-5:])   # 输出: World
print(s[::-1])  # 输出: dlroWolleH (反转字符串)
  • 字符串查找
# 查找子串的位置
s = "HelloWorld"
print(s.find("World"))  # 输出: 5
print(s.index("World"))  # 输出: 5 (如果找不到会抛出异常)

# 统计子串出现次数
print(s.count("l"))  # 输出: 3
  • 字符串替换
# 替换子串
s = "HelloWorld"
new_s = s.replace("World", "Python")
print(new_s)  # 输出: HelloPython
  • 字符串大小写转换
# 转换为大写
s = "hello"
print(s.upper())  # 输出: HELLO

# 转换为小写
s = "HELLO"
print(s.lower())  # 输出: hello

# 首字母大写
s = "hello world"
print(s.capitalize())  # 输出: Hello world

# 每个单词首字母大写
print(s.title())  # 输出: Hello World
  • 去除空白字符
# 去除两端空白字符
s = "  hello  "
print(s.strip())  # 输出: hello

# 去除左端空白字符
print(s.lstrip())  # 输出: hello  

# 去除右端空白字符
print(s.rstrip())  # 输出:   hello
  • 字符串分割
# 按空格分割字符串
s = "Hello World"
print(s.split())  # 输出: ['Hello', 'World']

# 按指定字符分割字符串
s = "apple,banana,orange"
print(s.split(','))  # 输出: ['apple', 'banana', 'orange']
  • 字符串格式化
# 使用 % 进行格式化
name = "Alice"
age = 25
print("My name is %s and I am %d years old." % (name, age))

# 使用 format() 方法
print("My name is {} and I am {} years old.".format(name, age))

# 使用 f-string (Python 3.6+)
print(f"My name is {name} and I am {age} years old.")

1.3 数字操作

在算法竞赛中,对数字的操作也非常重要,包括但不限于加减乘除、取模等。

  • 基本运算
# 加法
a = 5
b = 3
print(a + b)  # 输出: 8

# 减法
print(a - b)  # 输出: 2

# 乘法
print(a * b)  # 输出: 15

# 除法
print(a / b)  # 输出: 1.6666666666666667

# 整除
print(a // b)  # 输出: 1

# 取余
print(a % b)  # 输出: 2

# 幂运算
print(a ** b)  # 输出: 125
  • 数学函数
import math

# 绝对值
print(abs(-5))  # 输出: 5

# 最大值
print(max(1, 2, 3))  # 输出: 3

# 最小值
print(min(1, 2, 3))  # 输出: 1

# 四舍五入
print(round(3.7))  # 输出: 4

# 向上取整
print(math.ceil(3.2))  # 输出: 4

# 向下取整
print(math.floor(3.7))  # 输出: 3

# 开方
print(math.sqrt(16))  # 输出: 4.0

# 对数
print(math.log(10))  # 输出: 2.302585092994046

# 三角函数
print(math.sin(math.pi / 2))  # 输出: 1.0
  • 随机数生成
import random

# 生成一个随机整数
print(random.randint(1, 10))  # 输出: [1, 10] 之间的随机整数

# 生成一个随机浮点数
print(random.random())  # 输出: [0, 1) 之间的随机浮点数

# 从列表中随机选择一个元素
lst = [1, 2, 3, 4, 5]
print(random.choice(lst))  # 输出: 列表中的一个随机元素

# 打乱列表顺序
random.shuffle(lst)
print(lst)  # 输出: 打乱后的列表

二、常用数据结构的操控

2.1 列表(List)

列表是 Python 中最常用的数据结构之一,支持增删改查、排序、反转等操作。

  • 创建列表
# 创建空列表
lst = []

# 创建包含元素的列表
lst = [1, 2, 3, 4, 5]

# 使用 range() 创建列表
lst = list(range(1, 6))
print(lst)  # 输出: [1, 2, 3, 4, 5]
  • 访问元素
# 访问单个元素
lst = [1, 2, 3, 4, 5]
print(lst[0])  # 输出: 1
print(lst[-1])  # 输出: 5

# 访问子列表
print(lst[1:4])  # 输出: [2, 3, 4]
  • 添加元素
# 在末尾添加元素
lst = [1, 2, 3]
lst.append(4)
print(lst)  # 输出: [1, 2, 3, 4]

# 在指定位置插入元素
lst.insert(1, 0)
print(lst)  # 输出: [1, 0, 2, 3, 4]

# 合并两个列表
lst.extend([5, 6])
print(lst)  # 输出: [1, 0, 2, 3, 4, 5, 6]
  • 删除元素
# 删除指定位置的元素
lst = [1, 2, 3, 4, 5]
del lst[2]
print(lst)  # 输出: [1, 2, 4, 5]

# 删除指定值的元素
lst.remove(4)
print(lst)  # 输出: [1, 2, 5]

# 弹出最后一个元素
last = lst.pop()
print(last)  # 输出: 5
print(lst)  # 输出: [1, 2]

# 清空列表
lst.clear()
print(lst)  # 输出: []
  • 修改元素
# 修改指定位置的元素
lst = [1, 2, 3, 4, 5]
lst[2] = 0
print(lst)  # 输出: [1, 2, 0, 4, 5]
  • 查找元素
# 查找元素索引
lst = [1, 2, 3, 4, 5]
print(lst.index(3))  # 输出: 2

# 统计元素出现次数
print(lst.count(2))  # 输出: 1
  • 排序
# 升序排序
lst = [3, 1, 4, 1, 5, 9]
lst.sort()
print(lst)  # 输出: [1, 1, 3, 4, 5, 9]

# 降序排序
lst.sort(reverse=True)
print(lst)  # 输出: [9, 5, 4, 3, 1, 1]

# 自定义排序规则
lst = [("apple", 2), ("banana", 1), ("orange", 3)]
lst.sort(key=lambda x: x[1])
print(lst)  # 输出: [('banana', 1), ('apple', 2), ('orange', 3)]

# 多重排序
lst = [("apple", 2, 10), ("banana", 1, 5), ("orange", 3, 8)]
lst.sort(key=lambda x: (x[1], x[2]))
print(lst)  # 输出: [('banana', 1, 5), ('apple', 2, 10), ('orange', 3, 8)]
  • 反转
# 反转列表
lst = [1, 2, 3, 4, 5]
lst.reverse()
print(lst)  # 输出: [5, 4, 3, 2, 1]

2.2 元组(Tuple)

元组与列表类似,但它是不可变的,即一旦创建就不能修改。

  • 创建元组
# 创建空元组
tup = ()

# 创建包含元素的元组
tup = (1, 2, 3, 4, 5)

# 单个元素的元组需要加逗号
tup = (1,)
  • 访问元素
# 访问单个元素
tup = (1, 2, 3, 4, 5)
print(tup[0])  # 输出: 1
print(tup[-1])  # 输出: 5

# 访问子元组
print(tup[1:4])  # 输出: (2, 3, 4)
  • 元组解包
# 解包元组
tup = (1, 2, 3)
a, b, c = tup
print(a, b, c)  # 输出: 1 2 3

# 忽略部分元素
a, *rest = (1, 2, 3, 4, 5)
print(a, rest)  # 输出: 1 [2, 3, 4, 5]
  • 元组转换为列表
# 将元组转换为列表
tup = (1, 2, 3, 4, 5)
lst = list(tup)
print(lst)  # 输出: [1, 2, 3, 4, 5]

2.3 字典(Dictionary)

字典是一种键值对的数据结构,支持高效的查找、插入和删除操作。

  • 创建字典
# 创建空字典
dic = {}

# 创建包含键值对的字典
dic = {"apple": 2, "banana": 1, "orange": 3}

# 使用 dict() 函数创建字典
dic = dict(apple=2, banana=1, orange=3)
  • 访问元素
# 访问指定键对应的值
dic = {"apple": 2, "banana": 1, "orange": 3}
print(dic["apple"])  # 输出: 2

# 使用 get() 方法访问值(不存在时返回默认值)
print(dic.get("grape", 0))  # 输出: 0
  • 添加或修改元素
# 添加新键值对
dic["grape"] = 5
print(dic)  # 输出: {'apple': 2, 'banana': 1, 'orange': 3, 'grape': 5}

# 修改现有键对应的值
dic["apple"] = 10
print(dic)  # 输出: {'apple': 10, 'banana': 1, 'orange': 3, 'grape': 5}
  • 删除元素
# 删除指定键对应的项
del dic["banana"]
print(dic)  # 输出: {'apple': 10, 'orange': 3, 'grape': 5}

# 使用 pop() 方法删除并返回值
value = dic.pop("orange")
print(value)  # 输出: 3
print(dic)  # 输出: {'apple': 10, 'grape': 5}

# 清空字典
dic.clear()
print(dic)  # 输出: {}
  • 遍历字典
# 遍历键
for key in dic:
    print(key)

# 遍历值
for value in dic.values():
    print(value)

# 遍历键值对
for key, value in dic.items():
    print(key, value)

2.4 集合(Set)

集合是一个无序且不重复的元素集合,支持交集、并集、差集等操作。

  • 创建集合
# 创建空集合
s = set()

# 创建包含元素的集合
s = {1, 2, 3, 4, 5}

# 使用 set() 函数创建集合
s = set([1, 2, 3, 4, 5])
  • 添加元素
# 添加单个元素
s = {1, 2, 3}
s.add(4)
print(s)  # 输出: {1, 2, 3, 4}

# 添加多个元素
s.update([5, 6])
print(s)  # 输出: {1, 2, 3, 4, 5, 6}
  • 删除元素
# 删除指定元素
s = {1, 2, 3, 4, 5}
s.remove(3)
print(s)  # 输出: {1, 2, 4, 5}

# 如果元素不存在则抛出异常,使用 discard() 方法不会抛出异常
s.discard(6)
print(s)  # 输出: {1, 2, 4, 5}

# 弹出任意元素
elem = s.pop()
print(elem)  # 输出: 任意一个元素
print(s)  # 输出: 剩余的元素
  • 集合操作
# 交集
s1 = {1, 2, 3}
s2 = {2, 3, 4}
intersection = s1.intersection(s2)
print(intersection)  # 输出: {2, 3}

# 并集
union = s1.union(s2)
print(union)  # 输出: {1, 2, 3, 4}

# 差集
difference = s1.difference(s2)
print(difference)  # 输出: {1}

# 对称差集
symmetric_difference = s1.symmetric_difference(s2)
print(symmetric_difference)  # 输出: {1, 4}

2.5 优先队列(Heapq)

优先队列是一种特殊的队列,能够高效地获取最小或最大元素。Python 中可以使用 heapq 模块来实现优先队列。

  • 创建堆
import heapq

# 创建空堆
heap = []

# 创建包含元素的堆
heap = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
heapq.heapify(heap)
print(heap)  # 输出: [0, 2, 1, 6, 3, 5, 4, 7, 8, 9]
  • 插入元素
# 插入元素
heapq.heappush(heap, 10)
print(heap)  # 输出: [0, 2, 1, 6, 3, 5, 4,7, 8, 9, 10]

# 插入元素并保持堆的大小不变(替换最小元素)
heapq.heappushpop(heap, -1)
print(heap)  # 输出: [-1, 2, 1, 6, 3, 5, 4, 7, 8, 9]
7, 8, 9, 10]

# 插入元素并保持堆的大小不变(替换最小元素)
heapq.heappushpop(heap, -1)
print(heap)  # 输出: [-1, 2, 1, 6, 3, 5, 4, 7, 8, 9]
  • 弹出最小元素
# 弹出最小元素
min_element = heapq.heappop(heap)
print(min_element)  # 输出: -1
print(heap)  # 输出: [0, 2, 1, 6, 3, 5, 4, 7, 8, 9]
  • 获取 n 个最小/最大元素
# 获取 3 个最小元素
smallest_three = heapq.nsmallest(3, heap)
print(smallest_three)  # 输出: [0, 1, 2]

# 获取 3 个最大元素
largest_three = heapq.nlargest(3, heap)
print(largest_three)  # 输出: [9, 8, 7]

三、Python 的语法特性

3.1 语法糖(Syntactic Sugar)

Python 提供了许多简洁且高效的语法糖,使得代码更加易读和简洁。

  • 列表推导式(List Comprehension)
# 使用 for 循环创建列表
lst = []
for i in range(10):
    lst.append(i * i)
print(lst)  # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 使用列表推导式创建列表
lst = [i * i for i in range(10)]
print(lst)  # 输出: [0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

# 带条件的列表推导式
lst = [i * i for i in range(10) if i % 2 == 0]
print(lst)  # 输出: [0, 4, 16, 36, 64]
  • 字典推导式(Dictionary Comprehension)
# 使用 for 循环创建字典
dic = {}
for i in range(5):
    dic[i] = i * i
print(dic)  # 输出: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

# 使用字典推导式创建字典
dic = {i: i * i for i in range(5)}
print(dic)  # 输出: {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
  • 集合推导式(Set Comprehension)
# 使用 for 循环创建集合
s = set()
for i in range(10):
    s.add(i * i)
print(s)  # 输出: {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}

# 使用集合推导式创建集合
s = {i * i for i in range(10)}
print(s)  # 输出: {0, 1, 4, 9, 16, 25, 36, 49, 64, 81}
  • 生成器表达式(Generator Expression)
# 使用 for 循环创建生成器
gen = (i * i for i in range(10))
for num in gen:
    print(num, end=" ")  # 输出: 0 1 4 9 16 25 36 49 64 81

# 生成器表达式可以节省内存,因为它不会一次性生成所有元素
  • 多重赋值
# 多重赋值
a, b, c = 1, 2, 3
print(a, b, c)  # 输出: 1 2 3

# 交换两个变量的值
a, b = b, a
print(a, b)  # 输出: 2 1
  • 解包(Unpacking)
# 解包元组
tup = (1, 2, 3)
a, b, c = tup
print(a, b, c)  # 输出: 1 2 3

# 忽略部分元素
a, *rest = (1, 2, 3, 4, 5)
print(a, rest)  # 输出: 1 [2, 3, 4, 5]

# 解包字典
dic = {"name": "Alice", "age": 25, "city": "Beijing"}
name, age, city = dic.values()
print(name, age, city)  # 输出: Alice 25 Beijing
  • 链式比较
# 链式比较
x = 5
print(1 < x < 10)  # 输出: True
print(1 < x and x < 10)  # 等价于上面的链式比较
  • 三元运算符
# 三元运算符
x = 5
result = "even" if x % 2 == 0 else "odd"
print(result)  # 输出: odd
  • 枚举(enumerate)
# 使用 for 循环遍历索引和元素
lst = ["apple", "banana", "orange"]
for i in range(len(lst)):
    print(i, lst[i])

# 使用 enumerate() 函数简化代码
for i, item in enumerate(lst):
    print(i, item)
  • zip() 函数
# 合并两个列表
names = ["Alice", "Bob", "Charlie"]
ages = [25, 30, 35]

# 使用 for 循环合并
for i in range(len(names)):
    print(names[i], ages[i])

# 使用 zip() 函数简化代码
for name, age in zip(names, ages):
    print(name, age)

# 不同长度的列表会自动截断到最短长度
shorter = ["Alice", "Bob"]
longer = [25, 30, 35]
for name, age in zip(shorter, longer):
    print(name, age)

3.2 Python 的优势

Python 在算法竞赛中有许多独特的优势,以下是一些常见的优势:

  • 整形不会溢出:Python 中的整数类型没有固定的大小限制,可以表示任意大的整数。这在处理大数问题时非常方便。
# 计算大数的阶乘
import math
print(math.factorial(100))  # 输出: 93326215443944152681699238856266700490715968264381621468592963895217599993229915608941463976156518286253697920827223758251185210916864000000000000000000000000
  • 内置函数丰富:Python 提供了大量内置函数,可以直接使用而无需自己实现。
# 统计字符串中每个字符出现的次数
from collections import Counter
s = "hello world"
counter = Counter(s)
print(counter)  # 输出: Counter({'l': 3, 'o': 2, 'h': 1, 'e': 1, ' ': 1, 'w': 1, 'r': 1, 'd': 1})
  • 代码简洁易读:Python 的语法简洁,代码可读性强,减少了出错的可能性。
# 计算斐波那契数列的前 n 项
def fibonacci(n):
    a, b = 0, 1
    result = []
    while len(result) < n:
        result.append(a)
        a, b = b, a + b
    return result

print(fibonacci(10))  # 输出: [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]
  • 动态类型系统:Python 是动态类型语言,变量不需要声明类型,编写代码更加灵活。
# 动态类型示例
x = 5
print(x)  # 输出: 5

x = "Hello"
print(x)  # 输出: Hello
  • 丰富的标准库:Python 标准库提供了大量的模块和函数,可以直接使用这些工具来解决问题。
# 使用 bisect 模块进行二分查找
import bisect

lst = [1, 3, 5, 7, 9]
index = bisect.bisect_left(lst, 5)
print(index)  # 输出: 2

# 插入元素并保持有序
bisect.insort(lst, 4)
print(lst)  # 输出: [1, 3, 4, 5, 7, 9]

四、自带的算法库

Python 自带了许多常用的算法库,可以直接使用这些库来提高解题效率。

4.1 排序算法

Python 内置的 sorted() 函数和 list.sort() 方法可以对列表进行排序,默认是升序排序,也可以指定降序或自定义排序规则。

  • 基本排序
# 升序排序
lst = [3, 1, 4, 1, 5, 9]
sorted_lst = sorted(lst)
print(sorted_lst)  # 输出: [1, 1, 3, 4, 5, 9]

# 降序排序
sorted_lst = sorted(lst, reverse=True)
print(sorted_lst)  # 输出: [9, 5, 4, 3, 1, 1]

# 使用 list.sort() 方法原地排序
lst.sort()
print(lst)  # 输出: [1, 1, 3, 4, 5, 9]
  • 自定义排序规则
# 按绝对值排序
lst = [3, -1, 2, -4, 5]
sorted_lst = sorted(lst, key=abs)
print(sorted_lst)  # 输出: [-1, 2, 3, -4, 5]

# 按字符串长度排序
words = ["apple", "banana", "orange", "grape"]
sorted_words = sorted(words, key=len)
print(sorted_words)  # 输出: ['grape', 'apple', 'banana', 'orange']

# 按多个条件排序
students = [("Alice", 25), ("Bob", 30), ("Charlie", 25)]
sorted_students = sorted(students, key=lambda x: (x[1], x[0]))
print(sorted_students)  # 输出: [('Alice', 25), ('Charlie', 25), ('Bob', 30)]

4.2 查找算法

Python 提供了多种查找算法,如二分查找等。

  • 二分查找
# 使用 bisect 模块进行二分查找
import bisect

lst = [1, 3, 5, 7, 9]
index = bisect.bisect_left(lst, 5)
print(index)  # 输出: 2

# 插入元素并保持有序
bisect.insort(lst, 4)
print(lst)  # 输出: [1, 3, 4, 5, 7, 9]

4.3 数学运算

Python 提供了丰富的数学运算函数,可以直接使用这些函数来进行复杂的数学计算。

  • 常用数学函数
import math

# 绝对值
print(abs(-5))  # 输出: 5

# 最大值
print(max(1, 2, 3))  # 输出: 3

# 最小值
print(min(1, 2, 3))  # 输出: 1

# 四舍五入
print(round(3.7))  # 输出: 4

# 向上取整
print(math.ceil(3.2))  # 输出: 4

# 向下取整
print(math.floor(3.7))  # 输出: 3

# 开方
print(math.sqrt(16))  # 输出: 4.0

# 对数
print(math.log(10))  # 输出: 2.302585092994046

# 三角函数
print(math.sin(math.pi / 2))  # 输出: 1.0
  • 随机数生成
import random

# 生成一个随机整数
print(random.randint(1, 10))  # 输出: [1, 10] 之间的随机整数

# 生成一个随机浮点数
print(random.random())  # 输出: [0, 1) 之间的随机浮点数

# 从列表中随机选择一个元素
lst = [1, 2, 3, 4, 5]
print(random.choice(lst))  # 输出: 列表中的一个随机元素

# 打乱列表顺序
random.shuffle(lst)
print(lst)  # 输出: 打乱后的列表

五、Python 独有的技巧

5.1 字符串操作技巧

Python 的字符串操作非常强大,掌握一些技巧可以提高解题效率。

  • 字符串反转
# 使用切片反转字符串
s = "hello"
reversed_s = s[::-1]
print(reversed_s)  # 输出: olleh
  • 字符串去重
# 使用集合去重
s = "hello"
unique_chars = "".join(set(s))
print(unique_chars)  # 输出: ehol(注意:集合无序,结果可能不同)

# 保持顺序去重
from collections import OrderedDict
s = "hello"
unique_chars = "".join(OrderedDict.fromkeys(s))
print(unique_chars)  # 输出: helo
  • 字符串分割与拼接
# 分割字符串
s = "apple,banana,orange"
fruits = s.split(',')
print(fruits)  # 输出: ['apple', 'banana', 'orange']

# 拼接字符串
joined_string = ",".join(fruits)
print(joined_string)  # 输出: apple,banana,orange

5.2 列表操作技巧

Python 的列表操作也非常灵活,掌握一些技巧可以简化代码。

  • 列表反转
# 使用 reverse() 方法反转列表
lst = [1, 2, 3, 4, 5]
lst.reverse()
print(lst)  # 输出: [5, 4, 3, 2, 1]

# 使用切片反转列表
reversed_lst = lst[::-1]
print(reversed_lst)  # 输出: [5, 4, 3, 2, 1]
  • 列表去重
# 使用集合去重
lst = [1, 2, 2, 3, 4, 4, 5]
unique_lst = list(set(lst))
print(unique_lst)  # 输出: [1, 2, 3, 4, 5](注意:集合无序,结果可能不同)

# 保持顺序去重
from collections import OrderedDict
lst = [1, 2, 2, 3, 4, 4, 5]
unique_lst = list(OrderedDict.fromkeys(lst))
print(unique_lst)  # 输出: [1, 2, 3, 4, 5]
  • 列表切片
# 获取子列表
lst = [1, 2, 3, 4, 5]
sub_lst = lst[1:4]
print(sub_lst)  # 输出: [2, 3, 4]

# 获取每隔一个元素的子列表
every_other = lst[::2]
print(every_other)  # 输出: [1, 3, 5]

# 反转列表
reversed_lst = lst[::-1]
print(reversed_lst)  # 输出: [5, 4, 3, 2, 1]

5.3 其他技巧

  • 惰性求值
# 使用生成器表达式实现惰性求值
gen = (i * i for i in range(10))
for num in gen:
    print(num, end=" ")  # 输出: 0 1 4 9 16 25 36 49 64 81

# 生成器表达式可以节省内存,因为它不会一次性生成所有元素
  • 装饰器
# 定义一个简单的装饰器
def my_decorator(func):
    def wrapper():
        print("Before function call")
        func()
        print("After function call")
    return wrapper

@my_decorator
def say_hello():
    print("Hello")

say_hello()
# 输出:
# Before function call
# Hello
# After function call
  • 上下文管理器
# 使用 with 语句管理资源
with open('example.txt', 'w') as file:
    file.write('Hello, World!')
# 文件会在 with 语句块结束后自动关闭

# 自定义上下文管理器
class MyContextManager:
    def __enter__(self):
        print("Entering context")
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting context")

with MyContextManager() as manager:
    print("Inside context")
# 输出:
# Entering context
# Inside context
# Exiting context

六、Python 算法竞赛中的优化技巧

6.1 时间复杂度优化

在算法竞赛中,时间复杂度是衡量算法效率的重要指标。以下是一些常见的优化技巧:

  • 避免不必要的循环嵌套
# 不推荐:双重循环导致 O(n^2) 复杂度
lst = [1, 2, 3, 4, 5]
for i in range(len(lst)):
    for j in range(i + 1, len(lst)):
        print(lst[i], lst[j])

# 推荐:使用组合生成器简化代码并提高效率
from itertools import combinations
for pair in combinations(lst, 2):
    print(pair)
  • 使用内置函数和库
# 不推荐:手动实现排序
lst = [3, 1, 4, 1, 5, 9]
sorted_lst = []
while lst:
    min_val = min(lst)
    sorted_lst.append(min_val)
    lst.remove(min_val)

# 推荐:使用内置的 sorted() 函数
sorted_lst = sorted(lst)
  • 缓存计算结果(Memoization)
# 不推荐:每次递归都重新计算斐波那契数列
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n - 1) + fibonacci(n - 2)

# 推荐:使用缓存减少重复计算
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(10))  # 输出: 55

6.2 空间复杂度优化

空间复杂度同样重要,尤其是在处理大规模数据时。以下是一些常见的优化技巧:

  • 使用生成器代替列表
# 不推荐:创建一个大列表占用大量内存
large_list = [i * i for i in range(10**6)]

# 推荐:使用生成器表达式节省内存
large_gen = (i * i for i in range(10**6))
for num in large_gen:
    print(num, end=" ")
  • 原地修改数据结构
# 不推荐:创建新的列表进行排序
lst = [3, 1, 4, 1, 5, 9]
sorted_lst = sorted(lst)

# 推荐:使用 list.sort() 方法原地排序
lst.sort()
  • 使用集合去重
# 不推荐:使用列表去重可能导致 O(n^2) 复杂度
lst = [1, 2, 2, 3, 4, 4, 5]
unique_lst = []
for item in lst:
    if item not in unique_lst:
        unique_lst.append(item)

# 推荐:使用集合去重,时间复杂度为 O(n)
unique_set = set(lst)
unique_lst = list(unique_set)

6.3 并行与多线程

虽然 Python 的 GIL(全局解释器锁)限制了多线程的性能提升,但在某些场景下仍然可以利用多进程或异步编程来加速任务。

  • 多进程
# 使用 multiprocessing 模块实现多进程
import multiprocessing

def worker(num):
    """模拟耗时任务"""
    print(f"Worker {num} is working")

if __name__ == "__main__":
    processes = []
    for i in range(5):
        p = multiprocessing.Process(target=worker, args=(i,))
        processes.append(p)
        p.start()

    for p in processes:
        p.join()
  • 异步编程
# 使用 asyncio 实现异步编程
import asyncio

async def fetch_data():
    print("Fetching data...")
    await asyncio.sleep(1)  # 模拟网络请求
    print("Data fetched")

async def main():
    tasks = [fetch_data() for _ in range(5)]
    await asyncio.gather(*tasks)

asyncio.run(main())