Python优化Grouper函数以避免无元素

时间:2012-08-29 20:26:36

标签: python python-2.5 itertools python-2.4

您好我正在使用python的itertools中的Grouper函数来切割大块的select,其中(idlist)查询sqlite性能。问题是在chunksize的整个空间填充石斑鱼,即使列表要小得多,所以我不得不添加一个循环和比较,之前我想优化。

# 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

3 个答案:

答案 0 :(得分:8)

如果不是过滤掉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)]

答案 1 :(得分:3)

这样的东西?

>>> 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)

答案 2 :(得分:1)

您可以使用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()调用中。