美文网首页我爱编程Python
Python实现简单版linq

Python实现简单版linq

作者: 冰麟轻武 | 来源:发表于2018-04-13 00:26 被阅读0次

    一、

    虽说Python在数据处理方面天生挺强的
    但是对于一个C#开发人员来说没有linq还真是挺麻烦的

    二、

    反正造轮子也习惯了
    那就造一个玩玩吧

    三、

    完整的复制一遍C#中linq的功能还是需要很多时间的
    所以暂时只实现了一部分常用的功能
    以后想要更多在慢慢加吧

    四、

    还是做了一些本地化的事情的
    比如方法名都小写了...
    然后也有一些限制,比如一个linq()对象只能被操作一次
    因为Python中的iterable没有reset操作!!!

    class linq(object):
        def __init__(self, iterable):
            if not isinstance(iterable, Iterable):
                raise TypeError('参数类型错误')
            self.__end = False
            self.__iterable = iterable
    
        def __get_iterable(self):
            if self.__end:
                raise StopIteration('迭代器不可重复使用')
    
            self.__end = True
            return self.__iterable
    
        def all(self, predicate):
            return all(map(predicate, self.__get_iterable()))
    
        def any(self, predicate=None):
            return any(map(predicate, self.__get_iterable()))
    
        def where(self, predicate):
            return linq(filter(predicate, self.__get_iterable()))
    
        def max(self):
            return max(self.__get_iterable())
    
        def min(self):
            return min(self.__get_iterable())
    
        def average(self):
            count = 0
            total = 0.0
            for number in self.__get_iterable():
                total += number
                count += 1
            return total / count
    
        def union(self, iterable):
            return linq(self.__union(iterable))
    
        def __union(self, iterable):
            for x in self.__get_iterable():
                yield x
            for x in iterable:
                yield x
    
        def count(self):
            count = 0
            for number in self.__get_iterable():
                count += 1
            return count
    
        def first(self, defaultValue=None):
            return next(self.__get_iterable(), defaultValue)
    
        def last(self, defaultValue=None):
            it = self.__get_iterable()
            x = None
            b = False
            while True:
                try:
                    x = next(it)
                    b = True
                except StopIteration:
                    if b:
                        return x
                    return defaultValue
    
        def sum(self):
            return sum(self.__get_iterable())
    
        def tolist(self):
            return list(self.__get_iterable())
    
        def select(self, selector):
            return linq(map(selector, self.__get_iterable()))
    

    五、

    测试代码

    test_result = {
        "select-list": {
            "expected": linq([1, 2, 3, 4, 5, 6]).where(lambda x: x % 2 == 0).select(lambda x: x * 2).tolist(),
            "actual": [4, 8, 12]
        },
        "sum": {
            "expected": linq([1, 2, 3, 4, 5, 6]).where(lambda x: x % 2 == 0).sum(),
            "actual": 12
        },
        "max": {
            "expected": linq([1, 2, 3, 4, 5, 6]).max(),
            "actual": 6
        },
        "min": {
            "expected": linq([1, 2, 3, 4, 5, 6]).min(),
            "actual": 1
        },
        "all": {
            "expected": [linq([1, 2, 3, 4, 5, 6]).all(lambda x: x < 3),
                            linq([1, 2, 3, 4, 5, 6]).all(lambda x: x > 0), ],
            "actual": [False, True]
        },
        "any": {
            "expected": [linq([1, 2, 3, 4, 5, 6]).any(lambda x: x > 3),
                            linq([1, 2, 3, 4, 5, 6]).any(lambda x: x < 0), ],
            "actual": [True, False]
        },
        "average": {
            "expected": linq([1, 2, 3, 4, 5, 6]).average(),
            "actual": 3.5
        },
        "union": {
            "expected": linq([1, 2, 3, 4, 5, 6]).union([8, 9, 10]).tolist(),
            "actual": [1, 2, 3, 4, 5, 6, 8, 9, 10]
        },
        "count": {
            "expected": linq([1, 2, 3, 4, 5, 6]).where(lambda x: x > 1).count(),
            "actual": 5
        },
        "first": {
            "expected": linq([1, 2, 3, 4, 5, 6]).where(lambda x: x > 1).first(),
            "actual": 2
        },
        "last": {
            "expected": linq([1, 2, 3, 4, 5, 6]).where(lambda x: x < 4).last(),
            "actual": 3
        },
    }
    
    for name, result in test_result.items():
        expected = result["expected"]
        actual = result["actual"]
        if expected == actual:
            print('%s 测试成功!' % name)
        else:
            print('%s 测试失败!\n    应为: %s\n    实为: %s' % (name, actual, expected))
    
    

    六、

    相关文章

      网友评论

        本文标题:Python实现简单版linq

        本文链接:https://www.haomeiwen.com/subject/eijqkftx.html