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.
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.
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))
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 tuple
s, 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
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])