简体   繁体   中英

Return the different multiplicative combinations of a list of numbers in Python

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

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

without duplicates or equivalent lists, as seen above ([2,3] does not appear).

The reason for this is to find all the ways to multiply together the prime factorisation of a number. That is, from the prime factors of 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 have made myself clear, I wasn't sure how to phrase this question correctly.

One way you can do this: Use two nested loops to multiply each number in the list with each other number, then recurse on that new list. This is not very efficient, as you will have tons of duplicate function calls (eg for multiplying the 3 in (3, 2, 2, 2) with any of the three 2 s, but this can be helped with a bit of memoization (unfortunately, this means we have to convert between lists and tuples a lot). Still, for larger inputs it's 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)])

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM