# Idiomatic way of repeating items in a sequence.

Discussion in 'Python' started by alr, Jun 30, 2003.

1. ### alrGuest

I need to repeat each item in a list n times, like this function does:

def repeatitems(sequence, repetitions):
newlist = []
for item in sequence:
for i in range(repetitions):
newlist.append(item)
return newlist

Output:

>>> repeatitems(['a', 'b', 'c'], 3)

['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c']

Clear and simple. But i wonder if there is a more idiomatic way. Surely not this:

def repeatitems(sequence, repetitions):
return reduce(lambda l, i: l + i, [[item] * repetitions for item in sequence])

?

alr, Jun 30, 2003

2. ### Max MGuest

alr wrote:
> I need to repeat each item in a list n times, like this function does:
>
> def repeatitems(sequence, repetitions):
> newlist = []
> for item in sequence:
> for i in range(repetitions):
> newlist.append(item)
> return newlist

I would make just a minor change:

def repeatitems(sequence, repetitions):
newlist = []
for item in sequence:
newlist += repetitions*[item]
return newlist

regards Max M

Max M, Jun 30, 2003

3. ### Duncan BoothGuest

(alr) wrote in
news::

> I need to repeat each item in a list n times, like this function does:
>
> def repeatitems(sequence, repetitions):
> newlist = []
> for item in sequence:
> for i in range(repetitions):
> newlist.append(item)
> return newlist
>
> Output:
>
> >>> repeatitems(['a', 'b', 'c'], 3)

> ['a', 'a', 'a', 'b', 'b', 'b', 'c', 'c', 'c']
>
> Clear and simple. But i wonder if there is a more idiomatic way.

The most obvious one that springs to mind is just a slight simplification

def repeatitems(sequence, repetitions):
newlist = []
for item in sequence:
newlist.extend([item] * repetitions)
return newlist

--
Duncan Booth
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?

Duncan Booth, Jun 30, 2003
4. ### Peter OttenGuest

alr wrote:

> I need to repeat each item in a list n times, like this function does:
>
> def repeatitems(sequence, repetitions):
> newlist = []
> for item in sequence:
> for i in range(repetitions):
> newlist.append(item)
> return newlist
>

....
> But i wonder if there is a more idiomatic way.

def repeatItems(sequence, repetitions):
return [[item]*repetitions for item in sequence]

Peter Otten, Jun 30, 2003
5. ### Richard BrodieGuest

"Peter Otten" <> wrote in message news:bdpdd7\$iue\$00\$-online.com...

>
> def repeatItems(sequence, repetitions):
> return [[item]*repetitions for item in sequence]

Unfortunately that is equivalent to:

def repeatitems(sequence, repetitions):
newlist = []
for item in sequence:
newlist.append([item] * repetitions)
return newlist

and not:

def repeatitems(sequence, repetitions):
newlist = []
for item in sequence:
newlist.extend([item] * repetitions)
return newlist

Richard Brodie, Jun 30, 2003
6. ### Duncan BoothGuest

Duncan Booth <> wrote in
news:Xns93AA81EC76E7Eduncanrcpcouk@127.0.0.1:

> The most obvious one that springs to mind is just a slight
>
> def repeatitems(sequence, repetitions):
> newlist = []
> for item in sequence:
> newlist.extend([item] * repetitions)
> return newlist
>

Or, if you are in a "I've got a new toy to play with" mood you could use
itertools from Python 2.3 to obfuscate it somewhat:

from itertools import chain, izip, repeat
def repeatiterate(sequence, repetitions):
return chain(*izip(*repeat(sequence, repetitions)))

This version returns an iterator, so you might want to throw in a call to
'list' if you want to do anything other than iterating over the result.

--
Duncan Booth
int month(char *p){return(124864/((p[0]+p[1]-p[2]&0x1f)+1)%12)["\5\x8\3"
"\6\7\xb\1\x9\xa\2\0\4"];} // Who said my code was obscure?

Duncan Booth, Jun 30, 2003
7. ### Peter OttenGuest

Richard Brodie wrote:

> Unfortunately that is equivalent to:
>
> def repeatitems(sequence, repetitions):
> newlist = []
> for item in sequence:
> newlist.append([item] * repetitions)
> return newlist
>

.... but it looked so good. I should have tested it, though.
Je suis desole :-(

Peter Otten, Jun 30, 2003
8. ### Terry ReedyGuest

"alr" <> wrote in message
news:...
> I need to repeat each item in a list n times, like this function

does:

Is this really the right question? Any code that requires such an
n-repeat list *could* be rewritten (if you own it) to use the replist
in condensed form: (items, n). If this is not possible, one could
also define a replist class with a __getitem__(self, index) that
divides index by self.n and an __iter__() that returns an appropriate
generator.

Terry J. Reedy

Terry Reedy, Jun 30, 2003
9. ### John HunterGuest

>>>>> "alr" == alr <> writes:

alr> reduce(lambda l, i: l + i, [[item] * repetitions for item in

This doesn't look too bad to me, but perhaps list comprehensions are
clearer?

seq = ['a', 'b', 'c']
print [x for x in seq for x in seq]

John Hunter, Jun 30, 2003
10. ### John HunterGuest

>>>>> "alr" == alr <> writes:

alr> reduce(lambda l, i: l + i, [[item] * repetitions for item in
alr> sequence])

Oops, premature hit of send key. What I meant to say was

seq = ['a', 'b', 'c']
print [x for x in seq for i in range(len(seq))]

JDH

John Hunter, Jun 30, 2003
11. ### Jeff EplerGuest

Here's one:

def repeatitems(sequence, repetitions):
r = [None] * repetitions
return [i for i in sequence for j in r]

Here's another, using generator functions (so the return is an iterator,
not a list):

def repeatitems(sequence, repetitions):
r = [None] * repetitions
for item in sequence:
for i in r:
yield item

In both cases I've performed an "optimization" by precomputing a list
with len(repetitions) instead of computing it once for each item in
sequence. Whether this makes a difference, I don't know.

Jeff

Jeff Epler, Jun 30, 2003
12. ### Mike C. FletcherGuest

John Hunter wrote:

>This doesn't look too bad to me, but perhaps list comprehensions are
>clearer?
>
> seq = ['a', 'b', 'c']
> print [x for x in seq for x in seq]
>
>>> def repeat3( sequence, count=1 ):

.... return [x for x in sequence for i in range(count) ]
....
>>> repeat3( [2,3,4], 3 )

[2, 2, 2, 3, 3, 3, 4, 4, 4]

I *think* is what you were suggesting, and is indeed very clear. For
those into generators, this is fun (but has no huge advantage if you
wind up using repeat instead of irepeat, or if you're using small
sequences):

>>> from __future__ import generators
>>> def irepeat( sequence, count=1 ):

.... countSet = range(count)
.... for item in sequence:
.... for i in countSet:
.... yield item
....
>>> def repeat( sequence, count = 1 ):

.... return list(irepeat(sequence, count))
....
>>> repeat( [2,3,4], 3 )

[2, 2, 2, 3, 3, 3, 4, 4, 4]

Enjoy,
Mike

_______________________________________
Mike C. Fletcher
Designer, VR Plumber, Coder
http://members.rogers.com/mcfletch/

Mike C. Fletcher, Jun 30, 2003
13. ### alrGuest

Wow, tanks for alle the replies. My favourite is John Hunters/Bob
Gailers solution ([x for x in seq for i in range(repetitions)]). I had
forgotten that you could have nested for statements in list
literals... Aahz's point is taken. I happen to need to repeat lists of
strings (which are immutable), but that's not what i asked about now
is it.

--
Regards