from itertools import tee, chain, islice, izip
import random
import timeit


def prev_cur_next_1(sequence):
    index = 0
    while index < len(sequence):
        yield (sequence[index - 1] if index else None,
               sequence[index],
               sequence[index + 1] if index + 1 < len(sequence) else None)
        index += 1
    raise StopIteration


def prev_cur_next_2(list_arg):
    extended_list = [None]
    extended_list.extend(list_arg)
    extended_list.append(None)
    return [extended_list[i - 1:i + 2] for i in xrange(1, len(extended_list) - 1)]


def prev_cur_next_3(some_iterable):
    prevs, items, nexts = tee(some_iterable, 3)
    prevs = chain([None], prevs)
    nexts = chain(islice(nexts, 1, None), [None])
    return izip(prevs, items, nexts)


def prev_cur_next_4(seq):
    return zip(chain([None], seq), seq, chain(islice(seq, 1, None), [None]))


data = [random.random() for i in xrange(1000000)]

samples = [prev_cur_next_1, prev_cur_next_2, prev_cur_next_3, prev_cur_next_4]

for sample_fx in samples:
    interval = timeit.timeit(lambda: list(sample_fx(data)), number=1)
    print '%s executed in %.3f seconds' % (sample_fx, interval)
