Reputation: 335
I have
list = [a, b, c, d]
and
numbers = [2, 4, 3, 1]
I want to get a list of the type of:
new_list = [a, a, b, b, b, b, c, c, c, d]
This is what I have so far:
new_list=[]
for i in numbers:
for x in list:
for i in range(1,i+1):
new_list.append(x)
Upvotes: 7
Views: 8913
Reputation: 107347
As a general approach for any object (not only string) you can use itertools.repeat()
within a 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 a benchmark on 3 main approaches. Note that the last one onley 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
Upvotes: 5
Reputation: 10819
That's my solution, just to add a different one.
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']
Upvotes: 1
Reputation: 566
This will work regardless of whether a, b, c and d are variables or strings:
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 might want to uncomment the if statement (and indent the line underneath) to check if the lists have the same length, otherwise new_lst will only contain as many items as the shorter list.
This, this and the documentation section on nested list comprehensions are worth reading.
Upvotes: 1
Reputation: 85572
A nested list comprehension 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 "sub-loop" for _ in range(number)
repeats the value number
times.
Here L
can hold any object, not only 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 flattens the sub 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 exactly the desired result.
Upvotes: 5
Reputation: 421
If you are unsure of how list comprehensions 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)
Upvotes: 1
Reputation: 78554
Here's one way to do it using zip
, string multiplication and a 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
renders the builtin list function unusable.
If the items in lst
are not strings you can simply use a nested comprehension on range
, to duplicate the items in the list.
Upvotes: 12
Reputation: 7056
Assuming that both lists are the same length and the second is always a list of numbers, here is a solution without using zip
or any imports:
lst = ['a', 'b', 'c', 'd']
numbers = [2,4,3,1]
result = sum([[lst[i]]*numbers[i] for i in range(len(lst))],[])
Upvotes: 0
Reputation: 7584
Another way to do it with a loop would be:
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']
Upvotes: 1
Reputation: 215117
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']
Upvotes: 3