2017-09-08 3 views
0

私はPython反復子を取り込み、イテレータの反復子を返す関数を作成しようとしています。各項目は元の反復子からの固定サイズの項目です。言い換えれば:Pythonの反復子をページ分割する

paginate([a, b, c, d], 2) -> [[a,b],[c,d]] 

私のコード、これまでに動作しますが、イテレータの長さはページサイズで割り切れる場合は長さゼロのページを返します。

def paginate(iterator, pageSize): 
    hasMore = True 

    def pageIter(): 
     print (1) 
     try: 
      for _ in range(pageSize): 
       yield next(iterator) 
     except StopIteration as e: 
      nonlocal hasMore 
      hasMore = False 
      raise e 

    def pager(): 
      while hasMore: 
       yield pageIter() 
       if not hasMore: 
        raise StopIteration() 

    return pager() 

私はitertoolsのレシピを持っていることを承知していますが、そのコードはNone sの不完全なページを埋めるように思われます。

答えて

1

以下は、すべての反復可能オブジェクトで動作するはずだけではなく、一覧表示されます:

class Paginator: 
    def __init__(self, iterable, page_len=3): 
     self.iterable = iterable 
     self.page_len = page_len 

    def __iter__(self): 
     page = [] 
     for i in self.iterable: 
      page.append(i) 
      if len(page) == self.page_len: 
       yield page 
       page = [] 
     if page: 
      yield page 

p = Paginator([1, 2, 3, 4, 5, 6, 7], 3) 
for i in p: 
    print(i) 

出力:

[1, 2, 3] 
[4, 5, 6] 
[7] 
1

あなたはitertoolsからtakeレシピを使用することができます。

def take(n, iterable): 
    "Return first n items of the iterable as a list" 
    return list(islice(iterable, n)) 

そして、 :

def unchain(iterable, n): 
    iterable = iter(iterable) 
    while True: 
     result = take(n, iterable) 
     if result: 
      yield result 
     else: 
      raise StopIteration 

>>> list(unchain(['a', 'b', 'c', 'd'], 2)) 
[['a', 'b'], ['c', 'd']] 
>>> list(unchain(['a', 'b', 'c', 'd', 'e'], 2)) 
[['a', 'b'], ['c', 'd'], ['e']]