程序运行慢?你怕是写的假 Python

本文通过五个示例展示了如何利用Python的内置方法和高效编程技巧提升程序性能。从数组求平方和、字符串拼接、筛选奇数到数组相加和查找相同元素,分别比较了不同实现方式的效率,强调了使用sum函数、列表推导式、生成器表达式以及join方法在优化代码性能上的优势。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python 程序运行太慢的一个可能的原因是没有尽可能的调用内置方法,下面通过 5 个例子来演示如何用内置方法提升 PythGon 程序的性能1. 数组求平方和输入一个列表,要求计算出该列表中数字的的平方和。最终性能提升了 1.4 倍。首先创建一个长度为 10000 的列表。

arr = list(range(10000))

1.1 最常规的写法while 循环遍历列表求平方和。平均运行时间 2.97 毫秒。

def sum_sqr_0(arr):
    res = 0
    n = len(arr)
    i = 0
    while i < n:
        res += arr[i] ** 2
        i += 1
    return res
%timeit sum_sqr_0(arr)
2.97 ms ± 36.4 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

1.2 for range 代替 while 循环

避免 i += 1 的变量类型检查带来的额外开销。平均运行时间 2.9 毫秒。

def sum_sqr_1(arr):
    res = 0
    for i in range(len(arr)):
        res += arr[i] ** 2
    return res
%timeit sum_sqr_1(arr)
2.9 ms ± 137 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

1.3 for x in arr 代替 for range

避免 arr[i] 的变量类型检查带来的额外开销。平均运行时间 2.59 毫秒。

def sum_sqr_2(arr):
    res = 0
    for x in arr:
        res += x ** 2
    return res
%timeit sum_sqr_2(arr)
2.59 ms ± 89 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

1.4 sum 函数套用 map 函数

平均运行时间 2.36 毫秒

def sum_sqr_3(arr):
    return sum(map(lambda x: x**2, arr))
%timeit sum_sqr_3(arr)
2.36 ms ± 15.1 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

1.5 sum 函数套用生成器表达式

生成器表达式如果作为某个函数的参数,则可以省略掉 ()。平均运行时间 2.35 毫秒。

def sum_sqr_4(arr):
    return sum(x ** 2 for x in arr)
%timeit sum_sqr_4(arr)
2.35 ms ± 107 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

1. 6 sum 函数套用列表推导式

平均运行时间 2.06 毫秒。

def sum_sqr_5(arr):
    return sum([x ** 2 for x in arr])
%timeit sum_sqr_5(arr)
2.06 ms ± 27.2 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

2. 字符串拼接

输入一个列表,要求将列表中的字符串的前 3 个字符都拼接为一个字符串。最终性能提升了 2.1 倍。

首先创建一个列表,生成 10000 个随机长度和内容的字符串。

from random import randint

def random_letter():
    return chr(ord('a') + randint(0, 25))

def random_letters(n):
    return "".join([random_letter() for _ in range(n)])

strings = [random_letters(randint(1, 10)) for _ in range(10000)]

2.1 最常规的写法

while 循环遍历列表,对字符串进行拼接。平均运行时间 1.86 毫秒。

def concat_strings_0(strings):
    res = ""
    n = len(strings)
    i = 0
    while i < n:
        res += strings[i][:3]
        i += 1
    return res
%timeit concat_strings_0(strings)
1.86 ms ± 74.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

2.2 for range 代替 while 循环

避免 i += 1 的变量类型检查带来的额外开销。平均运行时间 1.55 毫秒。

def concat_strings_1(strings):
    res = ""
    for i in range(len(strings)):
        res += strings[i][:3]
    return res
%timeit concat_strings_1(strings)
1.55 ms ± 32.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

2.3 for x in strings 代替 for range

避免 strings [i] 的变量类型检查带来的额外开销。平均运行时间 1.32 毫秒。

def concat_strings_2(strings):
    res = ""
    for x in strings:
        res += x[:3]
    return res
%timeit concat_strings_2(strings)
1.32 ms ± 19.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

2.4 .join 方法套用生成器表达式

平均运行时间 1.06 毫秒。

def concat_strings_3(strings):
    return "".join(x[:3] for x in strings)
%timeit concat_strings_3(strings)
1.06 ms ± 15.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

2.5 .join 方法套用列表解析式

平均运行时间 0.85 毫秒。

def concat_strings_4(strings):
    return "".join([x[:3] for x in strings])
%timeit concat_strings_4(strings)
858 µs ± 14.5 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

3. 筛选奇数

输入一个列表,要求筛选出该列表中的所有奇数。最终性能提升了 3.6 倍。

首先创建一个长度为 10000 的列表。

arr = list(range(10000))

3.1 最常规的写法

创建一个空列表 res,while 循环遍历列表,将奇数 append 到 res 中。平均运行时间 1.03 毫秒。

def filter_odd_0(arr):
    res = []
    i = 0
    n = len(arr)
    while i < n:
        if arr[i] % 2:
            res.append(arr[i])
        i += 1
    return res
%timeit filter_odd_0(arr)
1.03 ms ± 34.1 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

3.2 for range 代替 while 循环

避免 i += 1 的变量类型检查带来的额外开销。平均运行时间 0.965 毫秒。

def filter_odd_1(arr):
    res = []
    for i in range(len(arr)):
        if arr[i] % 2:
            res.append(arr[i])
        i += 1
    return res
%timeit filter_odd_1(arr)
965 µs ± 4.02 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

3.3 for x in arr 代替 for range

避免 arr[i] 的变量类型检查带来的额外开销。平均运行时间 0.430 毫秒。

def filter_odd_2(arr):
    res = []
    for x in arr:
        if x % 2:
            res.append(x)
    return res
%timeit filter_odd_2(arr)
430 µs ± 9.25 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

3.4 list 套用 filter 函数

平均运行时间 0.763 毫秒。注意 filter 函数很慢,在 Python 3.6 里非常鸡肋。

def filter_odd_3(arr):
    return list(filter(lambda x: x % 2, arr))
%timeit filter_odd_3(arr)
763 µs ± 15.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

3.5 list 套用生成器表达式

平均运行时间 0.398 毫秒。

def filter_odd_4(arr):
    return list((x for x in arr if x % 2))
%timeit filter_odd_4(arr)
398 µs ± 16.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

3.6 带条件的列表推导式

平均运行时间 0.290 毫秒。

def filter_odd_5(arr):
    return [x for x in arr if x % 2]
%timeit filter_odd_5(arr)
290 µs ± 5.54 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

4. 两个数组相加

输入两个长度相同的列表,要求计算出两个列表对应位置的数字之和,返回一个与输入长度相同的列表。最终性能提升了 2.7 倍。

首先生成两个长度为 10000 的列表。

arr1 = list(range(10000))
arr2 = list(range(10000))

4.1 最常规的写法

创建一个空列表 res,while 循环遍历列表,将两个列表对应的元素之和 append 到 res 中。平均运行时间 1.23 毫秒。

def arr_sum_0(arr1, arr2):
    i = 0
    n = len(arr1)
    res = []
    while i < n:
        res.append(arr1[i] + arr2[i])
        i += 1
    return res
%timeit arr_sum_0(arr1, arr2)
1.23 ms ± 3.77 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

4.2 for range 代替 while 循环

避免 i += 1 的变量类型检查带来的额外开销。平均运行时间 0.997 毫秒。

def arr_sum_1(arr1, arr2):
    res = []
    for i in range(len(arr1)):
        res.append(arr1[i] + arr2[i])
    return res
%timeit arr_sum_1(arr1, arr2)
997 µs ± 7.42 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

4.3 for i, x in enumerate 代替 for range

部分避免 arr[i] 的变量类型检查带来的额外开销。平均运行时间 0.799 毫秒。

def arr_sum_2(arr1, arr2):
    res = arr1.copy()
    for i, x in enumerate(arr2):
        res[i] += x
    return res
%timeit arr_sum_2(arr1, arr2)
799 µs ± 16.7 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

4.4 for x, y in zip 代替 for range

避免 arr[i] 的变量类型检查带来的额外开销。平均运行时间 0.769 毫秒。

def arr_sum_3(arr1, arr2):
    res = []
    for x, y in zip(arr1, arr2):
        res.append(x + y)
    return res
%timeit arr_sum_3(arr1, arr2)
769 µs ± 12.2 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

4.5 列表推导式套用 zip

平均运行时间 0.462 毫秒。

def arr_sum_4(arr1, arr2):
    return [x + y for x, y in zip(arr1, arr2)]
%timeit arr_sum_4(arr1, arr2)
462 µs ± 3.43 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

5. 两个列表相同元素的数量

输入两个列表,要求统计两个列表相同元素的数量。其中每个列表内的元素都是不重复的。最终性能提升了 5000 倍。

首先创建两个列表,并将元素的顺序打乱。

from random import shuffle
arr1 = list(range(2000))
shuffle(arr1)
arr2 = list(range(1000, 3000))
shuffle(arr2)

5.1 最常规的写法

while 循环嵌套,判断元素 arr1[i] 是否等于 arr2[j],平均运行时间 338 毫秒。

def n_common_0(arr1, arr2):
    res = 0
    i = 0
    m = len(arr1)
    n = len(arr2)
    while i < m:
        j = 0
        while j < n:
            if arr1[i] == arr2[j]:
                res += 1
            j += 1
        i += 1
    return res
%timeit n_common_0(arr1, arr2)
338 ms ± 7.81 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

5.2 for range 代替 while 循环

避免 i += 1 的变量类型检查带来的额外开销。平均运行时间 233 毫秒。

def n_common_1(arr1, arr2):
    res = 0
    for i in range(len(arr1)):
        for j in range(len(arr2)):
            if arr1[i] == arr2[j]:
                res += 1
    return res
%timeit n_common_1(arr1, arr2)
233 ms ± 10.9 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)

5.3 for x in arr 代替 for range

避免 arr[i] 的变量类型检查带来的额外开销。平均运行时间 84.8 毫秒。

def n_common_2(arr1, arr2):
    res = 0
    for x in arr1:
        for y in arr2:
            if x == y:
                res += 1
    return res
%timeit n_common_2(arr1, arr2)
84.8 ms ± 1.38 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

5.4 使用 if x in arr2 代替内层循环

平均运行时间 24.9 毫秒。

def n_common_3(arr1, arr2):
    res = 0
    for x in arr1:
        if x in arr2:
            res += 1
    return res
%timeit n_common_3(arr1, arr2)
24.9 ms ± 1.39 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

5.4 使用更快的算法

将数组用.sort 方法排序,再进行单层循环遍历。把时间复杂度从 O(n2) 降低到 O(nlogn),平均运行时间 0.239 毫秒。

def n_common_4(arr1, arr2):
    arr1.sort()
    arr2.sort()
    res = i = j = 0
    m, n = len(arr1), len(arr2)
    while i < m and j < n:
        if arr1[i] == arr2[j]:
            res += 1
            i += 1
            j += 1
        elif arr1[i] > arr2[j]:
            j += 1
        else:
            i += 1
    return res
%timeit n_common_4(arr1, arr2)
329 µs ± 12.3 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

5.5 使用更好的数据结构

将数组转为集合,求交集的长度。平均运行时间 0.067 毫秒。

def n_common_5(arr1, arr2):
    return len(set(arr1) & set(arr2))
%timeit n_common_5(arr1, arr2)
67.2 µs ± 755 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

这里给大家分享一份Python全套学习资料,包括学习路线、软件、源码、视频、面试题等等,都是我自己学习时整理的,希望可以对正在学习或者想要学习Python的朋友有帮助!

优快云大礼包:全网最全《全套Python学习资料》免费分享🎁

😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

👉优快云大礼包🎁:全网最全《Python学习资料》免费分享(安全链接,放心点击)👈

1️⃣零基础入门

① 学习路线

对于从来没有接触过Python的同学,我们帮你准备了详细的学习成长路线图。可以说是最科学最系统的学习路线,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。
在这里插入图片描述

② 路线对应学习视频

还有很多适合0基础入门的学习视频,有了这些视频,轻轻松松上手Python~在这里插入图片描述

③练习题

每节视频课后,都有对应的练习题哦,可以检验学习成果哈哈!
在这里插入图片描述
因篇幅有限,仅展示部分资料

2️⃣国内外Python书籍、文档

① 文档和书籍资料

在这里插入图片描述

3️⃣Python工具包+项目源码合集

①Python工具包

学习Python常用的开发软件都在这里了!每个都有详细的安装教程,保证你可以安装成功哦!
在这里插入图片描述

②Python实战案例

光学理论是没用的,要学会跟着一起敲代码,动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。100+实战案例源码等你来拿!
在这里插入图片描述

③Python小游戏源码

如果觉得上面的实战案例有点枯燥,可以试试自己用Python编写小游戏,让你的学习过程中增添一点趣味!
在这里插入图片描述

4️⃣Python面试题

我们学会了Python之后,有了技能就可以出去找工作啦!下面这些面试题是都来自阿里、腾讯、字节等一线互联网大厂,并且有阿里大佬给出了权威的解答,刷完这一套面试资料相信大家都能找到满意的工作。
在这里插入图片描述
在这里插入图片描述

5️⃣Python兼职渠道

而且学会Python以后,还可以在各大兼职平台接单赚钱,各种兼职渠道+兼职注意事项+如何和客户沟通,我都整理成文档了。
在这里插入图片描述
在这里插入图片描述
上述所有资料 ⚡️ ,朋友们如果有需要 📦《全套Python学习资料》的,可以扫描下方二维码免费领取 🆓
😝有需要的小伙伴,可以点击下方链接免费领取或者V扫描下方二维码免费领取🆓

👉优快云大礼包🎁:全网最全《Python学习资料》免费分享(安全链接,放心点击)👈

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值