4

こんにちは、python の itertools の Grouper 関数を使用して、sqlite のパフォーマンスのために select where in(idlist) クエリの大きなチャンクをカットしています。問題は、リストがはるかに小さい場合でも、グルーパーがチャンクサイズのスペース全体を埋めるため、最適化する前にループと比較を追加する必要がありました。

# 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を使用

4

3 に答える 3

12

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)]
于 2012-08-29T20:42:59.200 に答える
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)
于 2012-08-29T20:29:43.067 に答える
1

filterとを利用できますmap

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()最後に、リストではなくタプルにしたい場合は、これを呼び出しでラップできます。

于 2012-08-29T20:34:22.157 に答える