一、引入
个人觉得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()等真的可以大大增加数据处理的效率。