0

I'm working on a Python program where I have to come up with all the ways to roll 9 4-sided dice. I've been trying to come up with a more concise way to write this line:

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)]:

I've seen syntax similar to:

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)]:

but this gives the error:

TypeError: 'int' object is not iterable

What's going on?

smci
  • 32,567
  • 20
  • 113
  • 146
Ashton Baker
  • 111
  • 3

3 Answers3

3

As Calum noted, you should use the built-in itertools for these common loops.

In your case, you would want:

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

range(1,5) represents the 4 sides of the die

repeat=9 represents the 9 dice you want to roll

See itertools.product for doc

Omega
  • 133
  • 6
1

you should look at itertools specifically looking at combinations and permutations

Calum
  • 2,110
  • 2
  • 22
  • 39
1

The simplest method is to use the itertools module. So in your particular case, we could do:

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

Which would produce a generator. If we were to iterate over it, we would see that it contains:

[(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)]

If we wanted the possible sums, we could easily extend this via sum and 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])

But we also know (via math!) that the range will be the closed set of [1*9, 4*9].

Bill Lynch
  • 80,138
  • 16
  • 128
  • 173