8

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!

0

7 Answers 7

13

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.

Sign up to request clarification or add additional context in comments.

1 Comment

>>> import itertools >>> def ncycle(iterable, n): ... for item in itertools.cycle(iterable): ... for i in range(n): ... yield item
6

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]

3 Comments

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)?
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.
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.
2
itertools.chain.from_iterable(itertools.repeat(item, repeat) for item in itertools.cycle(l))

Comments

1

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.

Comments

1
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))))

Comments

1

I do it this way:

from itertools import cycle, repeat, chain
flatten = chain.from_iterable # better name

def ncycle(xs, n):
    return flatten(repeat(x, n) for x in cycle(xs))

# example
for n,x in enumerate(ncycle('abcd', 2)):
    print(x, end=" ")
    if n > 9:
        print("")
        break
# output: a a b b c c d d a a b

Comments

0
[ "%d, %d" % (i, i) for i in [1, 2, 3, 4] * 4]

The last 4 there is the number of cycles.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.