Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

python now, next, n iteration

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
like image 783
beoliver Avatar asked Jun 22 '12 21:06

beoliver


People also ask

How does next () work in Python?

next() Return ValueThe next() function returns the next item from the iterator. If the iterator is exhausted, it returns the default value passed as an argument. If the default parameter is omitted and the iterator is exhausted, it raises the StopIteration exception.

What is __ next __ in Python?

The __next__() method must return the next item in the sequence. On reaching the end, and in subsequent calls, it must raise StopIteration . Here, we show an example that will give us the next power of 2 in each iteration.

Can you call next on an iterable?

To get the next value of the Iterable, call next() function on its iterator object. It will return the next value of the Iterable. Keep on calling this next() function to get all elements of iterable one by one.

What is ITER () in Python?

python iter() method returns the iterator object, it is used to convert an iterable to the iterator. Syntax : iter(obj, sentinel) Parameters : obj : Object which has to be converted to iterable ( usually an iterator ). sentinel : value used to represent end of sequence.


1 Answers

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')
like image 101
beoliver Avatar answered Nov 02 '22 16:11

beoliver