Loop over list n times

Question:

Say you have this:

foo = [1,2,3,4,5,6,7,8,9,10]
bar = 22

I want to get bar many values from foo, repeating from the start after reaching the end. So for these inputs, the results should be 1,2,3,4,5,6,7,8,9,10,1,2,3,4,5,6,7,8,9,10,1,2.

I have this working code:

foo = [1,2,3,4,5,6,7,8,9,10]
bar = 22

x = 0

for i in range(bar):
    print(foo[x])

    # increment
    if x == 9:
        x = 0
    # back to 1
    else:
        x += 1

but is there a shorter way, that doesn’t use a temporary variable, x?

Asked By: user16118039

||

Answers:

You’re probably looking for the modulo operator:

foo = [1,2,3,4,5,6,7,8,9,10]
bar = 22

for i in range(bar):
    print(foo[i % len(foo)])

This will solve your question as posed, but see also 0x5453’s answer for a more general solution using itertools.

Answered By: Kemp

you don’t need loops at all:

foo = [1,2,3,4,5,6,7,8,9,10]
bar = 22
big_list = foo * bar #you could do this more memory efficiently by working out how many times you need to join the list based on its length.
print(list[0:bar])

Here’s the ‘memory efficient’ way of doing it, not quite as easy to decipher, you could use some helper variables to split out each part of the calculation. Having additional variables isn’t necessarily a bad thing!

foo = [1,2,3,4,5,6,7,8,9,10]
bar = 22
print(foo * (int(bar/len(foo)))+foo[0:(bar%len(foo))])
Answered By: JeffUK

While Kemp’s solution does work, I believe a more pythonic solution is to use the itertools package:

import itertools
foo = [1,2,3,4,5,6,7,8,9,10]
bar = 22
for i in itertools.islice(itertools.cycle(foo), bar):
    print(i)

cycle creates an endlessly repeating iterator over the specified iterable. After we consume the 10, the iterator will be back at 1.

islice works like the typical list slicing syntax, but it works on iterators and generators in addition to containers. We can use that to take bar items from the iterator.

This is a bit more flexible because it doesn’t require that foo be subscriptable. In other words, this will work even if:

  • foo is an iterator (e.g. foo = iter(foo))
  • foo is a generator (e.g. foo = (x*2 for x in foo))
  • foo is a special proxy object like dict_keys or dict_values (e.g. foo = {x: str(x) for x in foo}.keys())
Answered By: 0x5453
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.