# circular iteration

Discussion in 'Python' started by Flavio codeco coelho, Jan 21, 2005.

1. ### Flavio codeco coelhoGuest

hi,

is there a faster way to build a circular iterator in python that by doing this:

c=['r','g','b','c','m','y','k']

for i in range(30):
print c[i%len(c)]

thanks,

Flávio

Flavio codeco coelho, Jan 21, 2005

2. ### Duncan BoothGuest

Flavio codeco coelho wrote:

> hi,
>
> is there a faster way to build a circular iterator in python that by
> doing this:
>
> c=['r','g','b','c','m','y','k']
>
> for i in range(30):
> print c[i%len(c)]
>
> thanks,
>
> Flávio
>

>>> import itertools
>>> c=['r','g','b','c','m','y','k']
>>> circ = itertools.cycle(c)
>>> for i in range(30):

print circ.next(),

r g b c m y k r g b c m y k r g b c m y k r g b c m y k r g
>>>

Duncan Booth, Jan 21, 2005

3. ### Simon BrunningGuest

On 21 Jan 2005 08:31:02 -0800, Flavio codeco coelho <> wrote:
> hi,
>
> is there a faster way to build a circular iterator in python that by doing this:
>
> c=['r','g','b','c','m','y','k']
>
> for i in range(30):
> print c[i%len(c)]

I don''t know if it's faster, but:

>>> import itertools
>>> c=['r','g','b','c','m','y','k']
>>> for i in itertools.islice(itertools.cycle(c), 30):

.... print i

--
Cheers,
Simon B,
,
http://www.brunningonline.net/simon/blog/

Simon Brunning, Jan 21, 2005
4. ### Fredrik LundhGuest

"Flavio codeco coelho" wrote:

> is there a faster way to build a circular iterator in python that by doing this:
>
> c=['r','g','b','c','m','y','k']
>
> for i in range(30):
> print c[i%len(c)]

have you benchmarked this, and found it lacking, or are you just trying
to optimize prematurely?

</F>

Fredrik Lundh, Jan 21, 2005
5. ### Alex MartelliGuest

Simon Brunning <> wrote:
...
> > is there a faster way to build a circular iterator in python that by

doing this:
> >
> > c=['r','g','b','c','m','y','k']
> >
> > for i in range(30):
> > print c[i%len(c)]

>
> I don''t know if it's faster, but:
>
> >>> import itertools
> >>> c=['r','g','b','c','m','y','k']
> >>> for i in itertools.islice(itertools.cycle(c), 30):

> ... print i

Whenever you're using itertools, the smart money's on "yes, it's
faster";-).

E.g., on a slow, old iBook...:

kallisti:~ alex\$ python -mtimeit -s'c="rgbcmyk"' 'for i in range(30):
c[i%len(c)]'
10000 loops, best of 3: 47 usec per loop

kallisti:~ alex\$ python -mtimeit -s'c="rgbcmyk"; import itertools as it'
'for i in it.islice(it.cycle(c),30): i'
10000 loops, best of 3: 26.4 usec per loop

Of course, if you do add back the print statements they'll take orders
of magnitude more time than the cyclic access, so /F's point on
premature optimization may well be appropriate. But, if you're doing
something VERY speedy with each item you access, maybe roughly halving
the overhead for the cyclic access itself MIGHT be measurable (maybe
not; it IS but a few microseconds, after all).

I like itertools' approach because it's higher-abstraction and more
direct. Its blazing speed is just a trick to sell it to conservative
curmudgeons who don't see abstraction as an intrinsic good -- some of
those are swayed by microseconds;-)

Alex

Alex Martelli, Jan 22, 2005