【问题标题】:Python Optimize Grouper Function to avoid None elementsPython优化Grouper函数以避免None元素
【发布时间】:2012-08-29 20:26:36
【问题描述】:

您好,我正在使用 python 的 itertools 中的 Grouper 函数来减少大量 select where in(idlist) 查询以提高 sqlite 性能。问题是即使列表小得多,grouper 也会填充块大小的整个空间,所以我必须添加一个循环和比较,在此之前我要优化。

# input list shorter than grouper chunk size
input = (1,2,3,4,5)

grouper(10,input)
# desired output = (1,2,3,4,5)
# actual output = (1,2,3,4,5,None,None,None,None,None)

# current fix for this issue
list_chunks = tuple(tuple(n for n in t if n) for t in grouper(10, input))

我认为必须有一种方法可以在没有这种循环和比较的情况下做到这一点。

注意:使用python 2.5

【问题讨论】:

    标签: python python-2.5 itertools python-2.4


    【解决方案1】:

    如果不是过滤掉None 条目,而是重写grouper() 以返回您想要的内容是一个选项,您可以使用itertools.islice 使用以下解决方案:

    def grouper(n, iterable):
        it = iter(iterable)
        x = tuple(islice(it, n))
        while x:
            yield x
            x = tuple(islice(it, n))
    

    或者更短的等价物(稍微难以理解):

    def grouper(n, iterable):
        it = iter(iterable)
        return iter(lambda: tuple(islice(it, n)), ())
    

    例子:

    >>> list(grouper(5, range(12)))
    [(0, 1, 2, 3, 4), (5, 6, 7, 8, 9), (10, 11)]
    

    【讨论】:

      【解决方案2】:

      这样的?

      >>> filter(bool, (1,2,3,4,5,None,None,None,None,None))
      (1, 2, 3, 4, 5)
      

      对于更复杂的情况(例如,列表中有 0 或者您需要删除与 None 不同的内容),您可以实现自己的 lambda

      >>> filter(lambda n: n is not None, (0,1,2,3,4,5,None,None,None,None,None))
      (0, 1, 2, 3, 4, 5)
      

      甚至

      >>> from functools import partial
      >>> from operator import ne
      >>> filter(partial(ne, None), (0,1,2,3,4,5,None,None,None,None,None))
      (0, 1, 2, 3, 4, 5)
      

      【讨论】:

      • 请注意,这也会删除空字符串、空数据结构、0False
      【解决方案3】:

      你可以使用filtermap

      map(lambda x: filter(bool, x), grouper(10, my_input))
      

      这是一个例子:

      >>> my_input = (1,2,3,4,5,6,7,8,9,1,2,3,3)
      >>> map(lambda x: filter(bool, x), list(grouper(10, my_input)))
      [(1, 2, 3, 4, 5, 6, 7, 8, 9, 1), (2, 3, 3)]
      

      最后,如果你希望它是一个元组而不是一个列表,你可以将它包装在一个 tuple() 调用中。

      【讨论】:

      • 改用filter(None, ...)
      猜你喜欢
      • 2019-04-07
      • 1970-01-01
      • 2021-08-18
      • 2020-05-27
      • 1970-01-01
      • 1970-01-01
      • 2011-02-21
      • 1970-01-01
      • 2018-09-09
      相关资源
      最近更新 更多