Return various multiplicative combinations of a list of numbers in Python

I have a list of numbers, and I want to return a 2D list, preferably ordered from the largest to the smallest (although I can do this later) of all possible combinations of multiplication (to get the product of the original list) using all the elements of the list without duplicates. That is, if I have a list [1, 2, 3], I want it to return

[[3, 2, 1], [3, 2], [6, 1], [6]]

without duplicates or equivalent lists as shown above ([2,3] not displayed).

The reason for this is to find all the ways to multiply the total factorization of a number. That is, from the main coefficients 24 (2, 2, 2, 3) I want it to return

[[3, 2, 2, 2], [4, 3, 2], [6, 4], [6, 2, 2], [8, 3], [12, 2], [24]]

I hope I was convinced, I was not sure how to correctly formulate this question.

+4
source share
1 answer

One way to do this: use two nested loops to multiply each number in the list with each other, and then overwrite the new list. This is not very efficient since you will have many recurring function calls (for example, to multiply 3in (3, 2, 2, 2)by any of the three 2s, but this might be a bit of a reminder (unfortunately, this means that we need to translate a lot between lists and tuples). However, for large entrances this is not very fast.

def memo(f):
    f.cache = {}
    def _f(*args, **kwargs):
        if args not in f.cache:
            f.cache[args] = f(*args, **kwargs)
        return f.cache[args]
    return _f

@memo
def mult_comb(factors):
    result = set()
    result.add(tuple(sorted(factors)))
    for i, f1 in enumerate(factors):
        factors2 = list(factors[:i] + factors[i+1:])
        for k in range(i, len(factors2)):
            factors2[k] *= f1
            result.update(mult_comb(tuple(factors2)))
            factors2[k] /= f1
    return result

Example:

>>> mult_comb((3,2,2,2))
set([(4, 6), (3, 8), (2, 12), (2, 3, 4), (24,), (2, 2, 6), (2, 2, 2, 3)])
+2
source

All Articles