Python:50个代码优化案例 - 甲篇

简介:优化Python代码可以显著提升程序的性能、降低资源消耗,并提高可维护性。通过优化代码可以使程序运行更快、减少内存和计算资源的使用,同时提升用户体验并增强系统的扩展性。常见的优化方法包括算法优化、减少重复计算、代码重构、利用内置函数及并行处理。优化过程需平衡性能与可读性,以确保代码在提升效率的同时仍保持清晰和易于维护。

历史攻略:

Pycharm:ssh远程代码调试和开发

Python:代码覆盖率工具coverage

Python:使用numba模块给代码提提速

Python:time、timeit、datetime统计代码运行时间

案例源码:

# -*- coding: utf-8 -*-
# time: 2024/7/30 23:46
# file: demo.py
# author: tom
# 微信公众号: 玩转测试开发

# 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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值