python now, next, n iteration
function, iterator, python
Solution
My proposal would be,
from collections import deque
def now_nxt_deque(iterable, n=1):
deq = deque(maxlen=n)
for i in iterable:
deq.append(i)
if len(deq) == n:
yield tuple(deq)
for i in now_nxt_deque("hello world", 3):
print(i)
('h', 'e', 'l')
('e', 'l', 'l')
('l', 'l', 'o')
('l', 'o', ' ')
('o', ' ', 'w')
(' ', 'w', 'o')
('w', 'o', 'r')
('o', 'r', 'l')
('r', 'l', 'd')
Problem
writing a general function that can iterate over any iterable returning now, next pairs. ``` def now_nxt(iterable): iterator = iter(iterable) nxt = iterator.__next__() for x in iterator: now = nxt nxt = x yield (now,nxt) for i in now_nxt("hello world"): print(i) ('h', 'e') ('e', 'l') ('l', 'l') ('l', 'o') ('o', ' ') (' ', 'w') ('w', 'o') ('o', 'r') ('r', 'l') ('l', 'd') ``` I have been thinking about the best way to write a function where the number of items in each tuple can be set. for example if it was ``` func("hello",n=3) ``` the result would be: ``` ('h','e','l') ('e','l','l') ('l','l','o') ``` I am new to using timeit, so please point out if I doing anything wrong here: ``` import timeit def n1(iterable, n=1): #now_nxt_deque from collections import deque deq = deque(maxlen=n) for i in iterable: deq.append(i) if len(deq) == n: yield tuple(deq) def n2(sequence, n=2): # now_next from itertools import tee iterators = tee(iter(sequence), n) for i, iterator in enumerate(iterators): for j in range(i): iterator.__next__() return zip(*iterators) def n3(gen, n=2): from itertools import tee, islice gens = tee(gen, n) gens = list(gens) for i, gen in enumerate(gens): gens[i] = islice(gens[i], i, None) return zip(*gens) def prin(func): for x in func: yield x string = "Lorem ipsum tellivizzle for sure ghetto, consectetuer adipiscing elit." print("func 1: %f" %timeit.Timer("prin(n1(string, 5))", "from __main__ import n1, string, prin").timeit(100000)) print("func 2: %f" %timeit.Timer("prin(n2(string, 5))", "from __main__ import n2, string, prin").timeit(100000)) print("func 3: %f" %timeit.Timer("prin(n3(string, 5))", "from __main__ import n3, string, prin").timeit(100000)) ``` results: ``` $ py time_this_function.py func 1: 0.163129 func 2: 2.383288 func 3: 1.908363 ```