111

How do I repeat each element of a list n times and form a new list? For example:

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

x1 = [1,1,1,2,2,2,3,3,3,4,4,4]

x * n doesn't work

for i in x[i]:
    x1 = n * x[i]

There must be a simple and smart way.

johan
  • 1,664
  • 2
  • 14
  • 30
user3720101
  • 1,365
  • 2
  • 14
  • 18
  • Related questions: [Circular list iterator in Python](https://stackoverflow.com/q/23416381/7851470), [Duplicate elements in a list](https://stackoverflow.com/q/14878538/7851470), [Repeat a list within a list X number of times](https://stackoverflow.com/q/16095865/7851470), [Best way to extend a list with itself N times](https://stackoverflow.com/q/46560385/7851470). – Georgy Oct 01 '19 at 21:00
  • Also: [How to repeat each of a Python list's elements n times with itertools only?](https://stackoverflow.com/q/45799233/7851470) – Georgy Oct 01 '19 at 21:09

14 Answers14

158

The ideal way is probably numpy.repeat:

In [16]:

x1=[1,2,3,4]
In [17]:

np.repeat(x1,3)
Out[17]:
array([1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4])
CT Zhu
  • 52,648
  • 17
  • 120
  • 133
68

In case you really want result as list, and generator is not sufficient:

import itertools
lst = range(1,5)
list(itertools.chain.from_iterable(itertools.repeat(x, 3) for x in lst))

Out[8]: [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
m.wasowski
  • 6,329
  • 1
  • 23
  • 30
60

You can use list comprehension:

[item for item in x for i in range(n)]

>>> x = [1, 2, 3, 4]
>>> n = 3
>>> new = [item for item in x for i in range(n)]
#[1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
A.J. Uppal
  • 19,117
  • 6
  • 45
  • 76
18

A simpler way to achieve this to multiply the list x with n and sort the resulting list. e.g.

>>> x = [1,2,3,4]
>>> n = 3
>>> a = sorted(x*n)
>>> a
>>> [1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
Sohaib Farooqi
  • 5,457
  • 4
  • 31
  • 43
9

A nested list-comp works here:

>>> [i for i in range(10) for _ in xrange(3)]
[0, 0, 0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9]

Or to use your example:

>>> x = [1, 2, 3, 4]
>>> n = 3
>>> [i for i in x for _ in xrange(n)]
[1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4]
mgilson
  • 300,191
  • 65
  • 633
  • 696
3
zAxe=[]
for i in range(5):
    zAxe0 =[i] * 3
    zAxe +=(zAxe0) # append allows accimulation of data 
3
 [myList[i//n] for i in range(n*len(myList))]
Holy_diver
  • 377
  • 1
  • 15
3

way 1:

def foo():
    for j in [1, 3, 2]:
        yield from [j]*5

way 2:

from itertools import chain
l= [3, 1, 2]
chain(*zip(*[l]*3))

way 3:

sum(([i]*5 for i in [2, 1, 3]), [])
AsukaMinato
  • 1,017
  • 12
  • 21
3

This will solve your issue:

x=[1,2,3,4]
n = 3
x = sorted(x * n)
user14623283
  • 47
  • 1
  • 2
1
import itertools

def expand(lst, n):
    lst = [[i]*n for i in lst]
    lst = list(itertools.chain.from_iterable(lst))
    return lst

x=[1,2,3,4]
n=3
x1 = expand(x,3)

print(x1)

Gives:

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

Explanation:

Doing, [3]*3 gives the result of [3,3,3], replacing this with n we get [3,3,3,...3] (n times) Using a list comprehension we can go through each elem of the list and perform this operation, finally we need to flatten the list, which we can do by list(itertools.chain.from_iterable(lst))

Dair
  • 15,910
  • 9
  • 62
  • 107
  • `itertools.chain(*x)` these days should be written as `itertools.chain.from_iterable(x)` – mgilson Jun 14 '14 at 23:13
  • 2
    No problem. I see that one relatively frequently. The problem with the former is that it resolves your iterable into a tuple by merit of the unpacking operator which partially defeats the wonderfully laziness of `itertools`. – mgilson Jun 14 '14 at 23:15
0

If you want to modify the list in-place, the best way is to iterate from the back and assign a slice of what was previously one item to a list of that item n times.

This works because of slice assignment:

>>> ls = [1, 2, 3]
>>> ls[0: 0+1]
[1]
>>> ls[0: 0+1] = [4, 5, 6]
>>> ls
>>> [4, 5, 6, 2, 3]
def repeat_elements(ls, times):
    for i in range(len(ls) - 1, -1, -1):
        ls[i: i+1] = [ls[i]] * times

Demo usage:

>>> a = [1, 2, 3]
>>> b = a
>>> b
[1, 2, 3]
>>> repeat_elements(b, 3)
>>> b
[1, 1, 1, 2, 2, 2, 3, 3, 3]
>>> a
[1, 1, 1, 2, 2, 2, 3, 3, 3]

(If you don't want to modify it in-place, you can copy the list and return the copy, which won't modify the original. This would also work for other sequences, like tuples, but is not lazy like the itertools.chain.from_iterable and itertools.repeat method)

def repeat_elements(ls, times):
    ls = list(ls)  # Makes a copy
    for i in range(len(ls) - 1, -1, -1):
        ls[i: i+1] = [ls[i]] * times
    return ls
Artyer
  • 31,034
  • 3
  • 47
  • 75
0

For base Python 2.7:

    from itertools import repeat
    def expandGrid(**kwargs):
        # Input is a series of lists as named arguments
        # output is a dictionary defining each combination, preserving names
        #
        # lengths of each input list
        listLens = [len(e) for e in kwargs.itervalues()] 
        # multiply all list lengths together to get total number of combinations
        nCombos = reduce((lambda x, y: x * y), listLens) 
        iDict = {}
        nTimesRepEachValue=1 #initialize as repeating only once
        for key in kwargs.keys():
            nTimesRepList=nCombos/(len(kwargs[key])*nTimesRepEachValue)
            tempVals=[] #temporary list to store repeated
            for v in range(nTimesRepList):
                indicesToAdd=reduce((lambda x,y: list(x)+list(y)),[repeat(x, nTimesRepEachValue) for x in kwargs[key]])
                tempVals=tempVals+indicesToAdd
            iDict[key] = tempVals
            # Accumulating the number of times needed to repeat each value
            nTimesRepEachValue=len(kwargs[key])*nTimesRepEachValue
        return iDict

    #Example usage:
    expandedDict=expandGrid(letters=["a","b","c","d"],nums=[1,2,3],both=["v",3])
Ross
  • 1
0
x=[1,2,3,4]
def f11(x,n):  
    l=[]
    for item in x:
        for i in range(n):
            l.append(item)
            
    return l

f11(x,2)
Henry Ecker
  • 34,399
  • 18
  • 41
  • 57
0

If working with array is okay,

np.array([[e]*n for e in x]).reshape(-1)

In my opinion it is very readable.

haneulkim
  • 4,406
  • 9
  • 38
  • 80