简介:优化Python代码可以显著提升程序的性能、降低资源消耗,并提高可维护性。通过优化代码可以使程序运行更快、减少内存和计算资源的使用,同时提升用户体验并增强系统的扩展性。常见的优化方法包括算法优化、减少重复计算、代码重构、利用内置函数及并行处理。优化过程需平衡性能与可读性,以确保代码在提升效率的同时仍保持清晰和易于维护。
案例源码:
- # -*- coding: utf-8 -*-
- # file: demo.py
- # 微信公众号: 城东书院
-
- # 1. 使用列表推导式代替循环
- def demo_001():
- # 优化前
- result0001 = []
- for i in range(5):
- result0001.append(i * i)
-
- # 优化后
- result0002 = [i * i for i in range(5)]
- print(result0001)
- print(result0002)
-
-
- # 2. 使用集合代替列表进行成员测试
- def demo_002():
- # 优化前
- my_list = [1, 2, 3, 4, 5]
- if 3 in my_list:
- print(f"3 in my_list")
-
- # 优化后
- my_set = {1, 2, 3, 4, 5}
- if 3 in my_set:
- print(f"3 in my_set")
-
-
- # 3. 使用内建函数 sum() 代替手动累加
- def demo_003():
- # 优化前
- total = 0
- for num in range(10):
- total += num
- print(total)
-
- # 优化后
- total = sum(range(10))
- print(total)
-
-
- # 4. 避免不必要的字符串连接
- def demo_004():
- strings = ['Life', 'is', 'short', 'We', 'use', 'Python']
- # 优化前
- result = ""
- for s in strings:
- result += " " + s
- print(result.lstrip())
-
- # 优化后
- result = " ".join(strings)
- print(result)
-
-
- # 5. 使用 enumerate() 代替手动索引
- def demo_005():
- my_list = ["a", "b", "c"]
- # 优化前
- for index in range(len(my_list)):
- print(f"{index} : {my_list[index]}")
-
- # 优化后
- for i, value in enumerate(my_list):
- print(f"{i} : {value}")
-
-
- # 6. 使用生成器代替列表
- def demo_006():
- # 优化前
- squares = [i * i for i in range(5)]
- print(squares)
-
- # 优化后
- squares = (i * i for i in range(10))
- for _ in squares:
- print(next(squares))
-
-
- # 7. 直接访问字典而非 get() 方法(当键存在时)
- def demo_007():
- my_dict = {"a": 1, "b": 2}
-
- # 优化前
- value = my_dict.get('a', 'default')
- print(value)
-
- # 优化后
- value = my_dict['a']
- print(value)
-
-
- # 8. 使用 defaultdict 代替手动初始化字典
- def demo_008():
- keys = ["c", "d"]
-
- # 优化前
- my_dict = {}
- for key in keys:
- if key not in my_dict:
- my_dict[key] = 0
- my_dict[key] += 1
- print(my_dict)
- # print(my_dict["e"]) # KeyError: 'e'
-
- # 优化后
- from collections import defaultdict
- my_dict = defaultdict(int)
- for key in keys:
- my_dict[key] += 1
-
- print(my_dict)
- print(my_dict["e"]) # 0
-
-
- # 9. 使用 set 去重而不是循环
- def demo_009():
- my_list = [1, 2, 2]
- # 优化前
- unique_list = []
- for item in my_list:
- if item not in unique_list:
- unique_list.append(item)
- print(unique_list)
-
- # 优化后
- my_list = [1, 2, 2]
- unique_list = list(set(my_list))
- print(unique_list)
-
-
- # 10. 使用 itertools 模块中的工具
- def demo_010():
- # 优化前
- result = []
- for a in range(3):
- for b in range(3):
- result.append((a, b))
- print(result)
-
- # 优化后
- from itertools import product
- result = list(product(range(3), repeat=2))
- print(result)
-
-
- # 11. 避免在循环中重复计算
- def demo_011():
- my_list = [1, 2, 3]
- # 优化前
- for i in range(len(my_list)):
- value = len(my_list)
- print(value)
-
- # 优化后
- list_length = len(my_list)
- for i in range(list_length):
- print(list_length)
-
-
- # 12. 使用 map() 代替循环
- def demo_012():
- numbers = [1, 2]
- # 优化前
- result = []
- for num in numbers:
- result.append(num * 2)
- print(result)
-
- # 优化后
- result = list(map(lambda x: x * 2, numbers))
- print(result)
-
-
- # 13. 使用 filter() 代替循环过滤
- def demo_013():
- numbers = [1, 2]
- # 优化前
- result = []
- for num in numbers:
- if num % 2 == 0:
- result.append(num)
- print(result)
-
- # 优化后
- result = list(filter(lambda x: x % 2 == 0, numbers))
- print(result)
-
-
- # 14. 避免在循环中重复调用函数
- def demo_014():
- my_list = ["ab", "bcd", "defg"]
- # 优化前
- for i in range(len(my_list)):
- value = my_list[i]
- if len(value) > 2:
- print(value)
-
- # 优化后
- for value in my_list:
- if len(value) > 2:
- print(value)
-
-
- # 15. 使用 list 列表解析代替 append()
- def demo_015():
- # 优化前
- result = []
- for i in range(5):
- result.append(i * 2)
- print(result)
-
- # 优化后
- result = [i * 2 for i in range(5)]
- print(result)
-
-
- # 16. 使用 bisect 查找插入点
- def demo_016():
- sorted_list = [2, 5, 8]
- target = 6
- # 优化前
- import bisect
- position = 0
- for index, value in enumerate(sorted_list):
- if value >= target:
- position = index
- break
- print(position)
-
- # 优化后
- import bisect
- position = bisect.bisect_left(sorted_list, target)
- print(position)
-
-
- # 17. 避免不必要的循环嵌套
- def demo_017():
- # 优化前
- result = []
- for a in range(3):
- for b in range(3):
- result.append(a * b)
- print(result)
-
- # 优化后
- result = [a * b for a in range(3) for b in range(3)]
- print(result)
-
-
- # 18. 使用 str.format() 代替拼接
- def demo_018():
- name = "Tom"
- age = 30
- # 优化前
- result = "Name: " + name + ", Age: " + str(age)
- print(result)
-
- # 优化后
- result = "Name: {}, Age: {}".format(name, age)
- print(result)
-
-
- # 19. 使用 f-strings(Python 3.6+)
- def demo_019():
- name = "Tom"
- age = 30
- # 优化前
- result = "Name: {}, Age: {}".format(name, age)
- print(result)
-
- # 优化后
- result = f"Name: {name}, Age: {age}"
- print(result)
-
-
- # 20. 使用 itertools.cycle 进行循环
- def demo_020():
- # 优化前
- my_list = [1, 2, 3]
- for i in range(3):
- print(my_list[i % len(my_list)])
-
- # 优化后
- from itertools import cycle
- count = 0
- for value in cycle(my_list):
- print(value)
- if count >= 2:
- break
- count += 1
-
-
- # 21. 避免模块和函数属性访问
- def demo_021():
- count = 10
-
- # 优化前
- import math
- result = []
- for x in range(count):
- result.append(math.sqrt(x))
- print(result)
-
- # 优化后
- from math import sqrt
- result = []
- for x in range(count):
- result.append(sqrt(x))
- print(result)
-
-
- # 22. 使用 timeit 测试代码性能
- def demo_022():
- # 优化前
- import time
-
- start = time.time()
- a = 10
- b = 10
- result = [a + b for i in range(10000000)]
- end = time.time()
- print(end - start)
-
- # 优化后
- import timeit
- print(timeit.timeit('a=10;b=10;result=[a+b for i in range(10000000)]', number=1))
-
-
- # 23. 使用 functools.lru_cache 缓存函数结果
- def demo_023():
- # 优化前
- def add_demo(x, y):
- print("开始计算x+y.")
- return x + y
-
- print(add_demo(1, 2))
- print(add_demo(1, 2))
-
- # 优化后
- # 函数只被执行了一次,第二次的调用直接输出了结果,使用了缓存起来的值。
- from functools import lru_cache
-
- @lru_cache(maxsize=None)
- def add_demo(x, y):
- print("开始计算x+y.")
- return x + y
-
- print(add_demo(1, 2))
- print(add_demo(1, 2))
-
-
- # 24. 使用 collections.Counter 计数
- def demo_024():
- # 优化前
- my_list = ['a', 'b', 'a']
- counts = {}
- for item in my_list:
- if item in counts:
- counts[item] += 1
- else:
- counts[item] = 1
- print(counts)
-
- # 优化后
- from collections import Counter
- counts = Counter(my_list)
- print(counts)
-
-
- # 25. 使用 re 模块进行正则表达式匹配
- def demo_025():
- text = "python"
- # 优化前
- if 'h' in text:
- print('Match found')
-
- # 优化后
- import re
- if re.search(r'h', text):
- print('Match found')
-
-
- # 26. 使用 zip() 同时遍历多个列表
- def demo_026():
- list1 = [1, 2, 3]
- list2 = ["a", "b", "c"]
-
- # 优化前
- for i in range(len(list1)):
- print(list1[i], list2[i])
-
- # 优化后
- for item1, item2 in zip(list1, list2):
- print(item1, item2)
-
- # 注意事项: 可能会缺失精度, 只按最短的列表遍历。
-
-
- # 27. 避免在循环中进行不必要的计算
- def demo_027():
- items = [-2, -1, 0, 1]
-
- def opposite_number(number):
- return 0 - number
-
- # 优化前
- for item in items:
- result = opposite_number(item)
- if result > 1:
- print("do something.")
-
- # 优化后
- precomputed_values = [opposite_number(item) for item in items]
- for result in precomputed_values:
- if result > 1:
- print("do something.")
-
-
- # 28. 使用 os.path.join() 代替字符串拼接路径
- def demo_028():
- import os
- directory = os.getcwd()
- filename = "python"
-
- # 优化前
- file_path = directory + "/" + filename
- print(file_path)
-
- # 优化后
- import os
- file_path = os.path.join(directory, filename)
- print(file_path)
-
-
- # 29. 避免在列表解析中进行不必要的计算
- def demo_029():
- def expensive_operation(x):
- return x + 1
-
- # 优化前
- results = [expensive_operation(x) for x in range(10) if expensive_operation(x) > 5]
- print(results)
-
- # 优化后
- results = [result for x in range(10) if (result := expensive_operation(x)) > 5]
- print(results)
-
-
- # 30. 使用 collections.deque 进行高效的队列操作
- def demo_030():
- # 类似list的容器,两端都能实现快速append和pop(双端队列)
-
- # 优化前
- queue = []
- queue.append(1)
- queue.append(2)
- queue.pop(0) # slow
- print(queue)
-
- # 优化后
- from collections import deque
- queue = deque()
- queue.append(1)
- queue.append(2)
- queue.popleft() # fast
- print(queue)
-
-
- # 31. 使用 with 语句管理资源
- def demo_031():
- # 优化前
- file = open('file.txt', 'r')
- data = file.read()
- print(data)
- file.close()
-
- # 优化后
- with open('file.txt', 'r') as file:
- data = file.read()
- print(data)
-
-
- # 32. 使用 args 和 kwargs 处理函数参数
- def demo_032():
- # 优化前
- def func(a, b, c):
- print(a, b, c)
-
- func(1, 2, 3)
-
- # 优化后
- def func(*args, **kwargs):
- for i in args:
- print(i)
-
- for k, v in kwargs.items():
- print(k, v)
-
- func(1, 2, 3, a=1, b=2)
-
-
- # 33. 使用 dict 的 fromkeys 方法初始化字典
- def demo_033():
- keys = [1, 2]
- # 优化前
- my_dict = {}
- for key in keys:
- my_dict[key] = 0
- print(my_dict)
-
- # 优化后
- my_dict = dict.fromkeys(keys, 0)
- print(my_dict)
-
-
- # 34. 避免不必要的函数调用
- def demo_034():
- a, b, c = 1, 2, 3
-
- def add(x, y):
- return x + y
-
- # 优化前
- result = add(add(a, b), c)
- print(result)
-
- # 优化后
-
- result = a + b + c
- print(result)
-
-
- # 35. 使用 itertools 遍历大数据集
- def demo_035():
- result = 0
- count = 100000
-
- # 优化前
- large_list = [i for i in range(count)]
- for item in large_list:
- result += item
- print(result)
-
- # 优化后
- result = 0
- from itertools import islice
- large_list = (item for item in range(count))
- for item in islice(large_list, count):
- result += item
- print(result)
-
-
- # 36. 优化循环中的条件判断
- def demo_036():
- # 优化前
- for i in range(5):
- if i % 2 == 0:
- print(i)
-
- # 优化后
- for i in range(0, 5, 2):
- print(i)
-
-
- # 37. 使用 sorted() 代替手动排序
- def demo_037():
- my_list = [2, 1, 3]
-
- # 优化前
- my_list.sort()
- print(my_list)
-
- # 优化后
- sorted_list = sorted(my_list)
- print(sorted_list)
-
-
- # 38. 避免在循环中频繁创建对象
- def demo_038():
- class Foo(object):
- def __init__(self):
- pass
-
- def run(self, number):
- print(f"{number} run.")
-
- # 优化前
- for i in range(3):
- obj = Foo()
- obj.run(i)
-
- # 优化后
- obj = Foo()
- for i in range(3):
- obj.run(i)
-
-
- # 39. 使用生成器代替大量数据集合
- def demo_039():
- # 优化前
- data = [x for x in range(4)]
- print(data)
-
- # 优化后
- def generate_data():
- for x in range(4):
- yield x
-
- data_generator = generate_data()
- print([i for i in data_generator])
-
-
- # 40. 避免不必要的重复计算
- def demo_040():
- def expensive_function(a):
- return a + 1
-
- x, y = 1, 2
-
- # 优化前
- result = expensive_function(x) + expensive_function(y)
- print(result)
-
- # 优化后
- result_x = expensive_function(x)
- result_y = expensive_function(y)
- result = result_x + result_y
- print(result)
-
-
- # 41. 使用 isinstance() 进行类型检查
- def demo_041():
- value = 888
- # 优化前
- if type(value) is int:
- print("It's an integer")
-
- # 优化后
- if isinstance(value, int):
- print("It's an integer")
-
-
- # 42. 使用 join() 合并多个字符串
- def demo_042():
- my_list = ["p", "y", "t", "h", "o", "n"]
- # 优化前
- result = " ".join([str(x) for x in my_list])
- print(result)
-
- # 优化后
- result = " ".join(map(str, my_list))
- print(result)
-
-
- # 43. 使用 any() 和 all() 优化布尔逻辑
- def demo_043():
- def positive_number(a):
- return a == abs(a)
-
- my_list = [-2, 2]
-
- # 优化前
- found = False
- for item in my_list:
- if positive_number(item):
- found = True
- break
- print(found)
-
- # 优化后
- found = any(positive_number(item) for item in my_list)
- print(found)
-
-
- # 44. 使用 os.path.exists() 检查文件存在性
- def demo_044():
- import os
-
- # 优化前
- if os.path.isfile('file.txt') or os.path.isdir('file.txt'):
- print('File exists')
-
- # 优化后
- if os.path.exists('file.txt'):
- print('File exists')
-
-
- # 45. 使用 functools.partial 创建部分函数
- def demo_045():
- # 优化前
- def add(x, y):
- return x + y
-
- add5 = lambda y: add(5, y)
- print(add5)
-
- # 优化后
- from functools import partial
- add5 = partial(add, 5)
- print(add5)
-
-
- # 46. 避免不必要的 try/except 处理
- def demo_046():
- my_dict = {"a": 1, "b": 2}
- key = "c"
-
- # 优化前
- try:
- result = my_dict[key]
-
- except KeyError:
- result = 'default'
- print(result)
-
- # 优化后
- result = my_dict.get(key, 'default')
- print(result)
-
-
- # 47. 使用 assert 进行条件检查
- def demo_047():
- # 优化前
- # if 0 > 2:
- # raise ValueError("ERROR")
- #
- # # 优化后
- # assert 0 > 2, "ERROR"
- pass
-
-
- # 48. 优化文件读取方式
- def demo_048():
- # 优化前
- with open('file.txt') as file:
- data = file.read().splitlines()
- print(data)
- # 优化后
- with open('file.txt') as file:
- data = list(file)
- print(data)
-
-
- # 49. 使用 itertools.chain 合并迭代器
- def demo_049():
- list1 = [1]
- list2 = [2, 3]
- list3 = [4, 5, 6]
- # 优化前
- result = list(list1 + list2 + list3)
- print(result)
-
- # 优化后
- from itertools import chain
- result = list(chain(list1, list2, list3))
- print(result)
-
-
- # 50. 使用 unittest 代替手动测试
- def demo_050():
- def func(a, b):
- return a + b
-
- # 优化前
- def test():
- expected_result = 5
- assert func(2, 3) == expected_result
-
- test()
-
- # 优化后
- import unittest
- class TestFunc(unittest.TestCase):
- def test_func(self):
- expected_result = 5
- self.assertEqual(func(2, 3), expected_result)
-
- unittest.main()
-
-
- if __name__ == '__main__':
- demo_list = [
- demo_001, demo_002, demo_003, demo_004, demo_005, demo_006, demo_007, demo_008, demo_009, demo_010,
- demo_011, demo_012, demo_013, demo_014, demo_015, demo_016, demo_017, demo_018, demo_019, demo_020,
- demo_021, demo_022, demo_023, demo_024, demo_025, demo_026, demo_027, demo_028, demo_029, demo_030,
- demo_031, demo_032, demo_033, demo_034, demo_035, demo_036, demo_037, demo_038, demo_039, demo_040,
- demo_041, demo_042, demo_043, demo_044, demo_045, demo_046, demo_047, demo_048, demo_049, demo_050
- ]
-
- for index, demo in enumerate(demo_list):
- print(f"demo-{index + 1} start.")
- demo()
- print(f"demo-{index + 1} finish.")
- print()
-