Python-在不同对象中使用 in 操作符的查找效率

文章对比了Python中list、tuple、set和dict使用in操作符查找元素的性能,发现set和dict在大量数据下具有更高的查找效率,平均时间复杂度分别为O(1)。
摘要由CSDN通过智能技术生成

背景

在Python中 in 操作符可以用于判断某个元素是否存在于当前对象中,而对于不同的Python对象,使用 in 操作符的处理效率是不一样的。

针对 4 种常见的Python数据类型进行测试:list、tuple、set、dict。

测试过程

我们用于测试的 4 种Python数据类型,分别为 data_list 、data_tuple、data_set、data_dict,测试过程中,它们所包含的元素都是相同的,均通过 random.randint(0, num) 随机生成,但它们的长度均为 num - 5 ,也就是说在 [0, num] 范围内,将有5个整数不在上面的对象中,我们需要把这5个整数找出来。

测试代码如下:

import time
import random


def speed_test(target_range, n):
    start_time = time.perf_counter()
    res = []
    for i in range(n):
        if i not in target_range:
            res.append(i)
    end_time = time.perf_counter()
    print(f"查找结果:{res},测试类型:{type(target_range)},耗时:{end_time - start_time}")


if __name__ == '__main__':
    for num in [5000, 10000, 15000, 20000, 50000, 100000]:
        data_set = set()
        while len(data_set) <= num - 5:
            data_set.add(random.randint(0, num))
        print(f"当 num={num} 时,得到如下结果:")
        data_list = list(data_set)
        data_tuple = tuple(data_set)
        data_dict = {key: "" for key in data_set}

        speed_test(data_list, num)
        speed_test(data_tuple, num)
        speed_test(data_set, num)
        speed_test(data_dict, num)

测试结果

当 num=5000 时,得到如下结果:
查找结果:[351, 995, 1282, 3146, 4852],测试类型:<class 'list'>,耗时:0.15133190000000002
查找结果:[351, 995, 1282, 3146, 4852],测试类型:<class 'tuple'>,耗时:0.14467089999999996
查找结果:[351, 995, 1282, 3146, 4852],测试类型:<class 'set'>,耗时:0.00023099999999998122
查找结果:[351, 995, 1282, 3146, 4852],测试类型:<class 'dict'>,耗时:0.00021889999999996634
当 num=10000 时,得到如下结果:
查找结果:[780, 2154, 2598, 3291, 7351],测试类型:<class 'list'>,耗时:0.6077627999999999
查找结果:[780, 2154, 2598, 3291, 7351],测试类型:<class 'tuple'>,耗时:0.5185474000000001
查找结果:[780, 2154, 2598, 3291, 7351],测试类型:<class 'set'>,耗时:0.0004927999999999599
查找结果:[780, 2154, 2598, 3291, 7351],测试类型:<class 'dict'>,耗时:0.0004933999999998662
当 num=15000 时,得到如下结果:
查找结果:[2607, 4291, 11776, 12019, 14191],测试类型:<class 'list'>,耗时:1.3486879000000003
查找结果:[2607, 4291, 11776, 12019, 14191],测试类型:<class 'tuple'>,耗时:1.2675163
查找结果:[2607, 4291, 11776, 12019, 14191],测试类型:<class 'set'>,耗时:0.0007324000000004105
查找结果:[2607, 4291, 11776, 12019, 14191],测试类型:<class 'dict'>,耗时:0.0007440000000000779
当 num=20000 时,得到如下结果:
查找结果:[3973, 5433, 9099, 14543, 16535],测试类型:<class 'list'>,耗时:2.328689099999999
查找结果:[3973, 5433, 9099, 14543, 16535],测试类型:<class 'tuple'>,耗时:2.3179461000000003
查找结果:[3973, 5433, 9099, 14543, 16535],测试类型:<class 'set'>,耗时:0.0010215999999996228
查找结果:[3973, 5433, 9099, 14543, 16535],测试类型:<class 'dict'>,耗时:0.0010110999999994874
当 num=50000 时,得到如下结果:
查找结果:[15335, 17874, 26501, 30213, 44994],测试类型:<class 'list'>,耗时:16.145702999999997
查找结果:[15335, 17874, 26501, 30213, 44994],测试类型:<class 'tuple'>,耗时:15.4256396
查找结果:[15335, 17874, 26501, 30213, 44994],测试类型:<class 'set'>,耗时:0.002693100000001891
查找结果:[15335, 17874, 26501, 30213, 44994],测试类型:<class 'dict'>,耗时:0.0028848999999979696
当 num=100000 时,得到如下结果:
查找结果:[5600, 14239, 18219, 89465, 97168],测试类型:<class 'list'>,耗时:66.6667215
查找结果:[5600, 14239, 18219, 89465, 97168],测试类型:<class 'tuple'>,耗时:59.850557699999996
查找结果:[5600, 14239, 18219, 89465, 97168],测试类型:<class 'set'>,耗时:0.0052613000000008014
查找结果:[5600, 14239, 18219, 89465, 97168],测试类型:<class 'dict'>,耗时:0.00611929999999461

分析及结论

  • list、tuple它们使用 in 操作符的查找效率相差不多,随着查找数据量的增大,list、tuple的处理效率变得越来越慢
  • set、dict它们使用 in 操作符的查找效率相差不多,随着查找数据量的增大,set、dict的处理效率变化不大。

综上,list、tuple、set、dict,使用 in 操作符查找的平均时间复杂度如下:

数据类型查找平均复杂度
listO(n)
tupleO(n)
setO(1)
dIctO(1)

 当我们在处理数据量大且需频繁查找元素时,最好使用 set、dict ,这样将会大幅度提升处理速度。


参考:https://www.cnblogs.com/wintest/p/15580617.html

  • 6
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值