Question

Everytime I try to solve some math problem such as finding a specific product of certain number of factors I do this in Python

for x in xrange(1,10):
    for y in xrange(1,10):
        for z in xrange(1,10):
           product = x * y * z
           if product == 36:
               print "factors : {0},{1},{2}".format(x,y,z)

It is very straightforward and gets the job done fast in this example, but I was wondering if you guys know an easier or simpler way to write this. Any ideas on how to do this without using that many for iterations or repeating almost the same code over and over. These is obviously for 3 factors, but the more factors I add the longer and more repetitive the code keeps getting. Any ideas on how to simplify code for this simple type of problem? thanks

Was it helpful?

Solution

Itertool's cartesian product simulates the effect of multiple nested for loops.

import itertools

for x, y, z in itertools.product(range(1,10), range(1,10), range(1,10)):
    product = x * y * z
    if product == 36:
        print "factors : {0},{1},{2}".format(x,y,z)

Result:

factors : 1,4,9
factors : 1,6,6
factors : 1,9,4
(...etc)

If the range is always the same for each of x,y, and z, you can specify it just once:

for x, y, z in itertools.product(range(1,10), repeat=3):

If you're sick of typing a zillion asterisks for the product = line, you can use reduce to multiply together an arbitrary number of arguments:

for factors in itertools.product(range(1,3), repeat=10):
    product = reduce(lambda x, y: x*y, factors)

Once your format string becomes unwieldy, you can depend on join to string together factors:

if product == 512:
    #use `map` to turn the factors into strings, first
    print "factors: " + ",".join(map(str, factors))

OTHER TIPS

Avoid duplicates by having y start at x. Calculate z instead of running another loop.

for x in xrange(1,10):
    for y in xrange(x,10):
        z, r = divmod(36, x*y)
        if r == 0:
            print "factors : {0},{1},{2}".format(x,y,z)

For more factors, I would use a recursive function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top