map_between をやってみる -slice使ったっていいじゃない編-

[1,2,3,4,5]を与えられたら[3,5,7,9]を返すようなプログラムを書く。

元の記事は以下。

map_between をやってみる - Study08.net 対シンバシ殲滅用人型機動兵器
リストの隣接要素を次々に処理する - 今川館

#! /usr/bin/env python
# -*- coding: utf-8 -*-     

from itertools import islice, imap

def mapbtw(func, it):
    return imap(func, it, islice(it, 1, None))

if __name__ == '__main__':
    import operator

    print list(mapbtw(operator.add, range(1,6)))
    print list(mapbtw(operator.add, xrange(1,6)))

意外と知られていないitertoolsの関数群。

追記

イテレータは前に突き進むよりトラックバックいただきました。
id:imagawa_yakataさんどうもです。
で、本題ですが、上記のmapbtwだとイテレータに対応していないとのこと。
確かにおっしゃる通りです。手抜きですw
一応改良版書いときます。完全にitertoolsの紹介になってますが。。。

#! /usr/bin/env python
# -*- coding: utf-8 -*-

from itertools import islice, imap, tee

def mapbtw(func, it):
    iter1, iter2 = tee(it)
    return imap(func, iter1, islice(iter2, 1, None))

if __name__ == '__main__':
    import operator

    def listlike():
        yield 1
        yield 2
        yield 3
        yield 4
        yield 5

    print list(mapbtw(operator.add, range(1,6)))
    print list(mapbtw(operator.add, xrange(1,6)))
    print list(mapbtw(operator.add, listlike()))

本来はitの型見て動作変えるのがいいのかしらね。ま、気にしない。

teeはイテレータをコピーしちゃう関数。tee(it,n)で好きなだけコピーできる。
ただし、注意点は、itとteeの戻り値の1個目は同じイテレータを指していること。(意外とハマる)

まぁ〜、あくまでも別解ってことで。