Question: Multiply all elements of a list together (another list index out of range issue)

Question

Multiply all elements of a list together (another list index out of range issue)

Answers 4
Added at 2017-01-01 20:01
Tags
Question

In a program I'm writing, I need to multiply each element of a list with all the other elements, like this:

List = [i1, i2, i3]

Result = [i1*i2, i1*i3, i2*i3]

I've been messing around with loops for a while now, but I can't seem to get it to work. This is what I have so far (doesn't work, I know why it doesn't work, just asking for advice):

def function():
    for j in range(len(list)):
        n = j+1
        for i in range(len(list)):

            if n+i > len(list):
                n -= 1
            x = factor[j] * factor[j+i]

            result.append(x)
    return
Answers
nr: #1 dodano: 2017-01-01 21:01
input_list = [1, 2, 3, 4]
result_list = []

for i in range(len(input_list)):
    for j in range(i + 1, len(input_list)):
        result_list.append(input_list[i] * input_list[j])

print(result_list)

Result:

[2, 3, 4, 6, 8, 12]
nr: #2 dodano: 2017-01-01 21:01
from itertools import combinations

xs = [1, 2, 3]
products = [x1 * x2 for x1, x2 in combinations(xs, 2)]
nr: #3 dodano: 2017-01-01 22:01
[v1 * list1[j] for i, v1 in enumerate(list1) for j in xrange(i)]

itertools shmitertools..

Though this is the second fastest answer here, it is a bit slower than itertools method, and stylistically slightly wanting

In [22]: list1 = range(1000)

In [23]: timeit [x1 * x2 for x1, x2 in combinations(list1, 2)]
10 loops, best of 3: 52.8 ms per loop

In [24]: timeit [v1 * list1[j] for i, v1 in enumerate(list1) for j in xrange(i)]
10 loops, best of 3: 55.7 ms per loop

In [25]: def slow_answer(input_list):
    result_list = []
    for i in range(len(input_list)):
        for j in range(i + 1, len(input_list)):
            result_list.append(input_list[i] * input_list[j])
    return result_list
   ....: 

In [26]: timeit slow_answer(list1)
10 loops, best of 3: 95 ms per loop
nr: #4 dodano: 2017-01-02 10:01

As FMc says, itertools is the simplest solution. However, it might be helpful to look at what's wrong with the code you gave, instead of just writing completely new code. There are three issues:
1. You use two different names for your list (list and factor).
2. You include products of the form factor[j]*factor[j] when i is 0.
3. What you do when i+n is out of range doesn't work -- it could still result in something out of range.
A possible solution to 3 is to simply break out of the inner loop at this point: if you're out of range, you don't want to do anything for this i or for larger i with the same j. So that would give

for j in range(len(factor)):
    n = j+1
    for i in range(len(factor)):
        # we are now going to look up factor[n+i] so need >=
        if n+i >= len(factor): 
            break
        # to ensure the second factor is later, use [n+i]>=j+1
        x = factor[j] * factor[n+i]
        result.append(x)

However, a better method to loop through the list like this is to use enumerate:

for j,x in enumerate(factor):
    # x is a list element, j is its index
    for y in factor[j+1:]:
        # loop through remaining elements by slicing
        result.append(x*y)
Source Show
◀ Wstecz