一、引入
個人覺得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()等真的可以大大增加數據處理的效率。