itertools
(0, 0, 0, 0)
(0, 0, 0, 1)
(0, 0, 1, 1)
(0, 1, 1, 1)
(1, 1, 1, 1)
random_combination_with_replacement_from_iterator
(0, 0, 0, 0) 19.89%
(0, 0, 0, 1) 20.08%
(0, 0, 1, 1) 20.01%
(0, 1, 1, 1) 19.88%
(1, 1, 1, 1) 20.14%
random_combination_with_replacement
(0, 0, 0, 0) 6.14%
(0, 0, 0, 1) 24.98%
(0, 0, 1, 1) 37.71%
(0, 1, 1, 1) 25.04%
(1, 1, 1, 1) 6.13%
random_combination_with_replacement_proposal
(0, 0, 0, 0) 20.17%
(0, 0, 0, 1) 19.82%
(0, 0, 1, 1) 20.18%
(0, 1, 1, 1) 19.88%
(1, 1, 1, 1) 19.95%
Documentation
The
randommodule has four recipes that are supposed to "efficiently make random selections from the combinatoric iterators in the itertools module". And their docstrings all say "Random selection from [iterator]". Both suggest they're equivalent torandom.choice(list(iterator)), just efficiently.For example,
itertools.combinations_with_replacement([0, 1], r=4)produces these five combinations:So
random.choice(list(iterator))would return one of those five with 20% probability each.But the
random_combination_with_replacementrecipe instead produces these probabilities:Here's an implementation that is equivalent to
random.choice(list(iterator)):One can view the combinations as the result of actually simulating r random draws with replacement, where the multiset
{0,0,1,1}indeed occurs more often, namely as0011,0101,0110, etc. But that is not the only valid view and isn't the view suggested by the documentation (as my first paragraph argued). Though if that view and the bias is the intention, then I suggest its documentation should mention the bias.Test code
Attempt This Online!
Test results
Linked PRs