Create duplicates in a list

I have

list = [a, b, c, d] 

and

 numbers = [2, 4, 3, 1] 

I want to get a list of types:

 new_list = [a, a, b, b, b, b, c, c, c, d] 

This is what I still have:

 new_list=[] for i in numbers: for x in list: for i in range(1,i+1): new_list.append(x) 
+8
python list
source share
9 answers

Here is one way to do this with zip , line multiplication, and list comprehension:

 lst = ['a', 'b', 'c', 'd'] numbers = [2 , 4, 3, 1] r = [x for i, j in zip(lst, numbers) for x in i*j] print(r) # ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] 

Pay attention to the choice of names when using Python. A name like list makes it impossible to use the built-in list function.

If the elements in lst are not strings, you can simply use the nested understanding on range to duplicate the elements in the list.

+10
source share

Working with a nested list works:

 L = ['a','b','c','d'] numbers = [2, 4, 3, 1] >>> [x for x, number in zip(L, numbers) for _ in range(number)] ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] 

The "subcycle" for _ in range(number) repeats the value of number times. Here L can contain any object, not just strings.

Example:

 L = [[1, 2, 3],'b','c', 'd'] numbers = [2, 4, 3, 1] [x for x, number in zip(L, numbers) for _ in range(number)] [[1, 2, 3], [1, 2, 3], 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] 

but this aligns the list:

 [x for i, j in zip(L, numbers) for x in i*j] [1, 2, 3, 1, 2, 3, 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] 

not quite the desired result.

+5
source share

As a general approach for any object (not just strings), you can use itertools.repeat() in the generator expression:

 def repeat_it(lst, numbers): return chain.from_iterable(repeat(i, j) for i, j in zip(lst, numbers)) 

Demo:

 In [13]: from itertools import repeat, chain In [21]: lst=[5,4,6,0] In [22]: list(repeat_it(lst, numbers)) Out[22]: [5, 5, 4, 4, 4, 4, 6, 6, 6, 0] In [23]: lst=['a','b','c','d'] In [24]: list(repeat_it(lst, numbers)) Out[24]: ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] 

Here is an example of three main approaches. Note that the last oneley works for strings:

 In [49]: lst = lst * 1000 In [50]: numbers = numbers * 1000 In [51]: %timeit list(chain.from_iterable(repeat(i, j) for i, j in zip(lst, numbers))) 1 loops, best of 3: 8.8 s per loop In [52]: %timeit [x for x, number in zip(lst, numbers) for _ in range(number)] 1 loops, best of 3: 12.4 s per loop In [53]: %timeit [x for i, j in zip(lst, numbers) for x in i*j] 1 loops, best of 3: 7.2 s per loop 
+4
source share

You can use numpy.repeat() as another option:

 import numpy as np np.repeat(lst, numbers).tolist() # ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] 
+2
source share

Another way to do this is with a loop:

 new_list = [] for number, item in zip(numbers, l): for i in range(number): new_list.append(item) 

Now we have:

 new_list = ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] 
+1
source share

If you donโ€™t know how lists work,

 myList=['a','b','c','d'] # not a good idea to use list as a name for your variable numbers=[2,4,3,1] new_list=[] for i in range(len(myList)): for j in range(numbers[i]): new_list.append(myList[i]) print(new_list) 
+1
source share

This will work regardless of whether the variables or strings are a, b, c and d:

 a = 1 b = 2.0 c = "cheese" d = ["c", "a", "k", "e"] lst = [a, b, c, d] numbers = [2, 4, 3, 1] # if len(lst) == len(numbers): new_lst = [i for i, j in zip(lst, numbers) for k in range(j)] 

You may need to uncomment the if statement (and flatten the line below it) to check if the lists are the same length, otherwise new_lst will only contain as many elements as the shorter list.

This , this, and should read the documentation section on nested lists .

+1
source share

This is my decision, just to add another.

 l = ['a', 'b', 'c', 'd'] n = [2, 4, 3, 1] r = [] for i,v in enumerate(l): r += list(v*n[i]) >>> r ['a', 'a', 'b', 'b', 'b', 'b', 'c', 'c', 'c', 'd'] 
+1
source share

Assuming both lists are the same length and the second is always a list of numbers, here is a solution without using zip or any import:

 lst = ['a', 'b', 'c', 'd'] numbers = [2,4,3,1] result = sum([[lst[i]]*numbers[i] for i in range(len(lst))],[]) 
0
source share

All Articles