Home > Software design >  Multiply a list by the elements of other list
Multiply a list by the elements of other list

Time:12-25

I have this list of list, with a series of values:

factors = [1,2,3]
values = [[1,2,3],[3,1,4],[5,5,2]]

I want to multiply each list1 in values, but the corresponding element of list1. I am trying with this:

factors = [1,2,3]
values = [[1,2,3],[3,1,4],[5,5,2]]
multiply = []
for i in factors:
    multiply = [values[i]*i]

But it does not work. The expected value would be:

[[1, 2, 3], [6, 2, 8], [15, 15, 6]]

CodePudding user response:

Try this:

factors = [1, 2, 3]
values = [[1, 2, 3], [1, 2, 3], [1, 2, 3]]

multiply = []
for idx, lst in enumerate(values):
    multiply.append([factors[idx] * x for x in lst])

print(multiply)

For a list comprehension version of the above code, see @Hommes answer

CodePudding user response:

Update: Given more general setup of the problem I changed the comprehension

Solution with list comprehension:

factors = [1, 2, 3]
values = [[1, 2, 3], [3, 1, 4], [5, 5, 2]]
multiply = [[factors[idx] * elem for elem in lst] for idx, lst in enumerate(values)]
Out[39]: [[1, 2, 3], [6, 2, 8], [15, 15, 6]]

CodePudding user response:

There is a few problems with the code as it is:

Python uses zero-indexing

The first element of a list in Python has the index 0. In your for loop:

for i in factor:
    multiply = [values[i]*i]

The last iteration will try to access values[3]. But values has only 3 elements, so the last element is values[2], not values[3].

Multiplication * of a list and an integer doesn't actually multiply

Multiplying a list by an Int, say n gives you a new list that concatenates the original n times. For example:

>>> [1, 2, 3] * 3
[1, 2, 3, 1, 2, 3, 1, 2, 3]

The most straightforward way of actually broadcasting the multiplication over the list is to use a 'list comprehension'. For example:

>>> [3*x for x in [1,2,3]]
[3, 6, 9]

Applying this into your example would look something like:

for i in factors:
    multiply = [i*x for x in values[i-1]]

You are only keeping the last calculation in multiply

Each go around your for loop you assign a new value to multiply, overwriting whatever was there previously. If you want to collect all your results, then you should append to the multiply list.

multiply.append([i*x for x in values[i-1]])

All together, your example is fixed as:

factors = [1,2,3]
values = [[1,2,3],[3,1,4],[5,5,2]]
multiply = []
for i in factors:
    multiply.append([i*x for x in values[i-1]])

Improvements

However, there are still ways to improve the code in terms of concision and readability.

The root of the problem is to multiply a list's elements by a number. * can't do it, but you can write your own function which can:

def multiply_list(X, n):
    return [n*x for x in X]

Then you can use this function, and a list comprehension, to remove the for loop:

multiply = [multiply_list(x, i) for (x, i) in zip(values, factors)]

Or, if you think it is readable, then you can just use the nested list comprehension, which is much more concise:

multiply = [[factor * x for x in value] for (value, factor) in zip(values, factors)]

CodePudding user response:

You can use list comprehension for a one liner. Try this

multiply = [[x * y for y in list1] for x in list1]
  • Related