diff options
author | Miss Islington (bot) <31488909+miss-islington@users.noreply.github.com> | 2018-01-13 19:21:15 (GMT) |
---|---|---|
committer | Raymond Hettinger <rhettinger@users.noreply.github.com> | 2018-01-13 19:21:15 (GMT) |
commit | cf4cd4bccbf7c8931a3c6209457c6f7add4c7b5c (patch) | |
tree | 23a8d17756dc8c4168d5e56e8cf53f5e87cf7940 /Doc/library | |
parent | 29b1aff71805df4c5b6f55c02bda94d07c044c81 (diff) | |
download | cpython-cf4cd4bccbf7c8931a3c6209457c6f7add4c7b5c.zip cpython-cf4cd4bccbf7c8931a3c6209457c6f7add4c7b5c.tar.gz cpython-cf4cd4bccbf7c8931a3c6209457c6f7add4c7b5c.tar.bz2 |
Add itertools recipe for directly finding the n-th combination (GH-5161) (#5174)
(cherry picked from commit d37258dd2e189141906bd234385096cd8e885d8d)
Diffstat (limited to 'Doc/library')
-rw-r--r-- | Doc/library/itertools.rst | 23 |
1 files changed, 23 insertions, 0 deletions
diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst index d01ce8f..700a13a 100644 --- a/Doc/library/itertools.rst +++ b/Doc/library/itertools.rst @@ -859,6 +859,29 @@ which incur interpreter overhead. indices = sorted(random.randrange(n) for i in range(r)) return tuple(pool[i] for i in indices) + def nth_combination(iterable, r, index): + 'Equivalent to list(combinations(iterable, r))[index]' + pool = tuple(iterable) + n = len(pool) + if r < 0 or r > n: + raise ValueError + c = 1 + k = min(r, n-r) + for i in range(1, k+1): + c = c * (n - k + i) // i + if index < 0: + index += c + if index < 0 or index >= c: + raise IndexError + result = [] + while r: + c, n, r = c*r//n, n-1, r-1 + while index >= c: + index -= c + c, n = c*(n-r)//n, n-1 + result.append(pool[-1-n]) + return tuple(result) + Note, many of the above recipes can be optimized by replacing global lookups with local variables defined as default values. For example, the *dotproduct* recipe can be written as:: |