• Python实现简易Linq


    一、引入

      个人觉得C#的Linq是非常好用的语法糖,对于List的处理非常方便且高效。但是在Python中没有现成的类似于Linq的类库,于是想着自己写一个。

    二、代码部分

    class LinQUtil(object):
        """
        模拟C#的linq功能
        """
    
        def __init__(self, collection):
            """
            初始化
            :param collection:需要处理的list
            """
            self.collection = collection
    
        def where(self, func):
            """
            根据where添加查询
            :param func: 处理的函数
            :return:
            """
            try:
                return list(filter(func, self.collection))
            except Exception as e:
                print(e)
                return list()
    
        def first_or_default(self, func):
            try:
                res = list(filter(func, self.collection))
                if res:
                    return res[0]
                else:
                    return dict()
            except Exception as e:
                print(e)
                return dict()
    
    
    def main():
        # 从数据库查询出形如:[{},{}...]的数据
        data_list = get_user_list_dal()
        data_list_where = LinQUtil(data_list).first_or_default(func=lambda x: x.get('city_id') == 73)
        print(data_list_where)
        print(len(data_list_where))
    
    
    if __name__ == '__main__':
        main()

    三、基于bisect库实现单条件的精确查找(效率提升)

      Python有一个库bisect,这个库本身是用来实现排序的,但是这个库中有一个bisect.bisect(data_list,data),这个就厉害了,可以查找该数值将会插入的位置并返回,而不会插入。衍生出来bisect_left 和 bisect_right 函数就可以用来实现上述LinQUtils类中的方法了,

      具体代码如下:

     1 #!/usr/bin/env python
     2 # -*- coding:utf-8 -*-
     3 # @Time:2020/4/21 11:02
     4 # @Software:PyCharm
     5 __author__ = "JentZhang"
     6 import bisect
     7 from utils.base_func import timer
     8 
     9 
    10 def get_list_by_key(data_list, val, key_val_list):
    11     """
    12     通过二分查找获取指定key和val的数据,LinQUtils的升级版
    13     :param data_list:数据集合嵌套数组,必须是排序之后的
    14     :param val:
    15     :param key_val_list:排序之后所有的指定key的val集合
    16     :return:
    17     """
    18     import bisect
    19     result = list()
    20     if key_val_list:
    21         # 获取集合中指定数据最左边的位置
    22         data_start = bisect.bisect_left(key_val_list, val)
    23         # 获取集合中指定数据最右边的位置
    24         data_end = bisect.bisect_right(key_val_list, val)
    25         if data_start < data_end:
    26             # 截取嵌套数组符合条件的数据
    27             data_where = data_list[data_start:data_end]
    28             result = data_where
    29 
    30     return result
    31 
    32 
    33 @timer
    34 def main():
    35     data_list = [i for i in range(10000000)]
    36     res = get_list_by_key(data_list, val=9695465, key_val_list=data_list)
    37     print(res)
    38 
    39 
    40 if __name__ == '__main__':
    41     main()

      执行结果:

      

       在一千万的数据中,这个方法只需要不到一秒的时间就能实现精确查找!

      针对LinQ中单个查询条件的筛选,完全可以借助bisect来实现,比filter()的方法快的多得多!!!!

    四、总结

      这里先简单实现一下where和first_or_default的功能,后面再慢慢补充其他的。。。。。。

      其实,实现linq基础类就是基于Python的高级函数 filter()

      使用这里的Linq使我的匹配数据的过程相较于原来使用list循环来做节省了一半左右的时间。

            灵活运用python的高级函数如:filter(),map(),reduce()等真的可以大大增加数据处理的效率。

  • 相关阅读:
    css3正方体效果
    单行文本溢出和多行文本溢出变省略号
    iscroll的滑动效果
    angular笔记
    html页面的css样式、meta最常用的最基本最常规的配置参数
    解决webstorm卡顿问题
    pc端网页的设计尺寸
    时间字符串解析成日期时间格式
    Inf2Cat, signability test failed.
    #pragma once 与 #ifndef 解析(转载)
  • 原文地址:https://www.cnblogs.com/JentZhang/p/12664659.html
Copyright © 2020-2023  润新知