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()等真的可以大大增加數據處理的效率。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM