构建一个变量,将多个枚举组合在一个巨大的列表中

时间:2011-12-20 01:37:43

标签: python list combinatorics

我想用最简单的方法来创建一个庞大的列表。

假设我有三个六面骰子,所以每个骰子的值都为randint(1,6)。 我想要一组包含所有可能的方法来组合这3个数字的值,所以它可以是die1 * die2 + die3,或者它可以是die1 ** die3 - die2等。

我想定义一些变量Z,它等于加法,减法,乘法等。这样,我可以说die1 Z die2 Z die3它会给我一个巨大的列表,而不必我输入它。这在Python中可行吗?任何想法都将不胜感激。

2 个答案:

答案 0 :(得分:2)

这里要知道的关键是你可以将函数作为参数传递给另一个函数(或列表中)。一旦你明白这个问题就会变得更容易解决。

如果你想要列表理解:

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]

请注意,其中包含“无”,其中正常发生除零。

如果你把它分成一个函数,它会更清晰。它需要两个数字列表和一个操作列表,并返回所有结果:

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

没有任何地方会发生除零。像results(funcs,die,results(funcs,die,die))一样使用以获得所有结果。

这两者在结果上都有很多重复,所以根据你真正想做的事情,你可能想要set而不是list

另外,只是想到了它,但根据你打算做什么,你可以让results代替返回一个发电机:

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

如果您正在处理非常大的结果集,但只想逐个查看它们,那么这比构建整个列表更好。

答案 1 :(得分:0)

我认为您正在尝试询问如何在python中为笛卡尔积更好地重载运算符。

尝试使用product中的itertools

from itertools import *
die_outcomes = [1,2,3,4,5,6]
list(product(product(die_outcomes, die_outcomes), die_outcomes))