Q:

Building a variable that combines several enumerations in an enormous list

I'd like to come up with the simplest way possible to create an enormous list. 
Let's say I have three six-sided dice, so they'll each have a value of randint(1,6).
I want the set of values that encompasses every possible way to combine those 3 numbers, so it could be die1 * die2 + die3 or it could be die1 ** die3 - die2, etc.
I'd like to define some variable Z which equals addition, subtraction, multiplcation, etc.  That way, I could say die1 Z die2 Z die3 and it would get me an enormous list, without me having to type it out.  Is this possible in Python? Any ideas would be greatly appreciated.

A:

The key thing to know here is that you can pass a function as an argument to another function (or in a list). Once you understand that this problem becomes much easier to solve.
If you want a list comprehension:
from operator import add,sub,mul,div
funcs = [add,sub,mul,div]
die = [1,2,3,4,5,6]

results = [f(x,y) if y != 0 else None for x in die for y in [g(z,w) for z in die for w in die for g in funcs] for f in funcs]

Note that contains "None" where a division by zero would have normally occurred.
It's way clearer if you split it out into a function though. It takes two lists of number and a list of operations and returns all results:
def results(funcs, xs, ys):
  out = []
  for f in funcs:
    for x in xs:
      for y in ys:
        try:
          out.append(f(x,y))
        except ZeroDivisionError:
          pass
  return out

This has nothing where a division by zero would have occurred. Use like results(funcs,die,results(funcs,die,die)) to get all results.
Both of these have a lot of duplicates in their outcomes, so depending on what you actually want to do you might want a set instead of a list.
Also, just thought of it, but depending on what you're planning to do you could get results to return a generator instead:
def results(funcs, xs, ys):
  for f in funcs:
    for x in xs:
      for y in ys:
        try:
          yield f(x,y)
        except ZeroDivisionError:
          pass

If you're working on really large result sets but only want to look at them one by one this is a better option than building the whole list.

