6
age = [19, 20, 21, 22, 23, 24, 25]
frequency = [2, 1, 1, 3, 2, 1, 1]
output_age = [19, 19, 20, 21, 22, 22, 22, 23, 23, 24, 25]

How do we create a new list which adds items from one list a number of times dependant on another list?

Thanks

jr100
  • 79
  • 2
  • By a 'number of times dependant on an another list' what *exactly* do you mean? The number of items or their values or? – Milan Velebit Aug 29 '18 at 10:48

7 Answers7

8

Use a list-comprehension:

output_age = [i for l in ([a]*f for a, f in zip(age, frequency)) for i in l]
#[19, 19, 20, 21, 22, 22, 22, 23, 23, 24, 25]

why?

We first zip together the age and frequency lists so we can iterate over them in unison. As so:

for a, f in zip(age, frequency):
    print(a, f)

gives:

19 2
20 1
21 1
22 3
23 2
24 1
25 1

Then we want to repeat each element, a, as many times as f determines. This can be done by creating a list and multiplying it. Just like:

[4] * 3
#[4, 4, 4]

We then need to unpack these values so we wrap this expression in a generator (indicated with brackets) and iterate over that. This flattens the list. Note that there are alternative ways of achieving this (such as using itertools.chain.from_iterable).


An alternative method would be to repeat the number, a, through iterating over a range object rather than multiplying a list to get the repetitions.

This method would look something like:

output_age = [a for a, f in zip(age, frequency) for _ in range(f)]
#[19, 19, 20, 21, 22, 22, 22, 23, 23, 24, 25]
Joe Iddon
  • 20,101
  • 7
  • 33
  • 54
3

Using itertools and zip

Ex:

from itertools import chain
age = [19, 20, 21, 22, 23, 24, 25]
frequency = [2, 1, 1, 3, 2, 1, 1]

print( list(chain.from_iterable([[i] * v for i,v in zip(age, frequency)])) )

Output:

[19, 19, 20, 21, 22, 22, 22, 23, 23, 24, 25]
  • Note: chain.from_iterable to flatten the list.
Rakesh
  • 81,458
  • 17
  • 76
  • 113
3

The simplest and easiest to understand way;

age = [19, 20, 21, 22, 23, 24, 25]
frequency = [2, 1, 1, 3, 2, 1, 1]

output_age = []
for age, freq in zip(age, frequency):
    for _ in range(freq):
        output_age.append(age)
ruohola
  • 21,987
  • 6
  • 62
  • 97
3

Here is a solution using zip and range

>>> age = [19, 20, 21, 22, 23, 24, 25]
>>> frequency = [2, 1, 1, 3, 2, 1, 1]
>>> [a for a,f in zip(age, frequency) for _ in range(f)]
[19, 19, 20, 21, 22, 22, 22, 23, 23, 24, 25]
Sunitha
  • 11,777
  • 2
  • 20
  • 23
1
age = [19, 20, 21, 22, 23, 24, 25]
frequency = [2, 1, 1, 3, 2, 1, 1]
new_list = zip(age, frequency)
output_age=[]
for x,y in new_list:
  for i in range(y):
    output_age.append(x)

output:

[19, 19, 20, 21, 22, 22, 22, 23, 23, 24, 25]

V Sree Harissh
  • 665
  • 5
  • 24
1

You can also do it using the sum function, although this is not recommended for production code:

age = [19, 20, 21, 22, 23, 24, 25]
frequency = [2, 1, 1, 3, 2, 1, 1]
output_age = sum([[age[i]] * frequency[i] for i in range(len(age))],[])
print(output_age)

Output:

[19, 19, 20, 21, 22, 22, 22, 23, 23, 24, 25]
Vasilis G.
  • 7,556
  • 4
  • 19
  • 29
0

You need:

import functools
output_age = functools.reduce(lambda x, y:x+y, [[age[i]] * frequency[i] for i in range(len(age))])
Sociopath
  • 13,068
  • 19
  • 47
  • 75
pfctgeorge
  • 698
  • 3
  • 9