views:

1379

answers:

5

I'm using Python to infinitely iterate over a list, repeating each element in the list a number of times. For example given the list:

l = [1, 2, 3, 4]

I would like to output each element two times and then repeat the cycle:

1, 1, 2, 2, 3, 3, 4, 4, 1, 1, 2, 2 ...

I've got an idea of where to start:

def cycle(iterable):
  if not hasattr(cycle, 'state'):
    cycle.state = itertools.cycle(iterable)
  return cycle.next()

 >>> l = [1, 2, 3, 4]
 >>> cycle(l)
 1
 >>> cycle(l)
 2
 >>> cycle(l)
 3
 >>> cycle(l)
 4
 >>> cycle(l)
 1

But how would I repeat each element?

Edit

To clarify this should iterate infinitely. Also I've used repeating the element twice as the shortest example - I would really like to repeat each element n times.

Update

Will your solution lead me to what I was looking for:

>>> import itertools
>>> def ncycle(iterable, n):
...   for item in itertools.cycle(iterable):
...     for i in range(n):
...       yield item
>>> a = ncycle([1,2], 2)
>>> a.next()
1
>>> a.next()
1
>>> a.next()
2
>>> a.next()
2
>>> a.next()
1
>>> a.next()
1
>>> a.next()
2
>>> a.next()
2

Thanks for the quick answers!

+1  A: 

Solution should be something like

iterable = [1, 2, 3, 4]
n = 2

while (True):
  for elem in iterable:
    for dummy in range(n):
      print elem # or call function, or whatever

Edit: added 'While (True)' to iterate indefinitely.

Roberto Liffredo
+6  A: 

You could do it with a generator pretty easily:

def cycle(iterable):
    while True:
        for item in iterable:
            yield item
            yield item

x=[1,2,3]
c=cycle(x)

print [c.next() for i in range(10)]  // prints out [1,1,2,2,3,3,1,1,2,2]
Adam Rosenfield
Again, I am not 100% sure to have understood the question, but aren't generators a bit an overkill for a simple problem like returning an item twice (or n times)?
Roberto Liffredo
It's 5 lines. How can that be overkill? And if the alternative is building a list, that's impossible, because it's infinite length.
recursive
Why to create a function in the first place? You could reach the same results with a simple nested loop, without the need for a generator,Reading the loop, even a novice immediately understand the meaning of the code, while with generators you have to trust the name of the function.
Roberto Liffredo
+9  A: 

How about this:

import itertools

def bicycle(iterable, repeat=1):
    for item in itertools.cycle(iterable):
        for _ in xrange(repeat):
            yield item

c = bicycle([1,2,3,4], 2)
print [c.next() for _ in xrange(10)]

EDIT: incorporated bishanty's repeat count parameter and Adam Rosenfield's list comprehension.

Will Harris
>>> import itertools>>> def ncycle(iterable, n):... for item in itertools.cycle(iterable):... for i in range(n):... yield item
jb
This is such a sweet answer. I wish I could do +10.
PEZ
A: 
[ "%d, %d" % (i, i) for i in [1, 2, 3, 4] * 4]

The last 4 there is the number of cycles.

PEZ
A: 
import itertools as it

def ncycle(iterable, n=1):
    if n == 1:
        return it.cycle(iterable)
    return it.cycle(it.chain(*it.izip(*([iterable]*n))))