骰子的笛卡尔积的嵌套计算
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)]
如果我们想要可能的总和,我们可以通过 sum
和 set
轻松扩展它:
>>> 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]
的闭集。
我正在开发一个 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)]
如果我们想要可能的总和,我们可以通过 sum
和 set
轻松扩展它:
>>> 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]
的闭集。