骰子的笛卡尔积的嵌套计算

Nested computation of Cartesian-product of dice rolls

我正在开发一个 Python 程序,我必须想出所有方法来掷 9 个 4 面骰子。我一直在尝试想出一种更简洁的方式来编写这一行:

for n in [sum([a, b, c, d, e, f, g, h, i]) for a in range(1, 5) for b in range(1, 5) for c in range(1, 5) for d in range(1, 5) for e in range(1, 5) for f in range(1, 5) for g in range(1, 5) for h in range(1, 5) for i in range(1, 5)]:

我见过类似于以下的语法:

for n in [sum([a, b, c, d, e, f, g, h, i]) for a, b, c, d, e, f, g, h, i in range(1, 5)]:

但这给出了错误:

TypeError: 'int' object is not iterable

怎么回事?

你应该看看 itertools 特别是组合和排列

正如 Calum 指出的那样,您应该为这些常见循环使用内置的 itertools。

在你的情况下,你会想要:

import itertools
results = [sum(x) for x in itertools.product(range(1,5),repeat=9)]

range(1,5)代表骰子的4面

repeat=9代表你要掷的9个骰子

请参阅 itertools.product 文档

最简单的方法是使用itertools模块。因此,在您的特定情况下,我们可以这样做:

import itertools
itertools.combinations_with_replacement(range(1, 5), 9))

这会产生一个发电机。如果我们要遍历它,我们会看到它包含:

[(1, 1, 1, 1, 1, 1, 1, 1, 1),
 (1, 1, 1, 1, 1, 1, 1, 1, 2),
 (1, 1, 1, 1, 1, 1, 1, 1, 3),
 (1, 1, 1, 1, 1, 1, 1, 1, 4),
 (1, 1, 1, 1, 1, 1, 1, 2, 2),
 (1, 1, 1, 1, 1, 1, 1, 2, 3),
 ...
 (3, 3, 4, 4, 4, 4, 4, 4, 4),
 (3, 4, 4, 4, 4, 4, 4, 4, 4),
 (4, 4, 4, 4, 4, 4, 4, 4, 4)]

如果我们想要可能的总和,我们可以通过 sumset 轻松扩展它:

>>> set(sum(dice) for dice in itertools.combinations_with_replacement(range(1, 7), 9))
set([9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54])

但我们也知道(通过数学!)范围将是 [1*9, 4*9] 的闭集。