https://github.com/python/cpython/commit/f9a40c386d4d07dab1c15c6618807306a5119818
commit: f9a40c386d4d07dab1c15c6618807306a5119818
branch: main
author: Raymond Hettinger <[email protected]>
committer: rhettinger <[email protected]>
date: 2025-09-04T10:50:29-05:00
summary:

Add random_derangement recipe gh-138377

files:
M Doc/library/random.rst

diff --git a/Doc/library/random.rst b/Doc/library/random.rst
index b1120b3a4d8eb4..e9cebf46d57b01 100644
--- a/Doc/library/random.rst
+++ b/Doc/library/random.rst
@@ -630,7 +630,8 @@ Recipes
 -------
 
 These recipes show how to efficiently make random selections
-from the combinatoric iterators in the :mod:`itertools` module:
+from the combinatoric iterators in the :mod:`itertools` module
+or the :pypi:`more-itertools` project:
 
 .. testcode::
    import random
@@ -661,6 +662,17 @@ from the combinatoric iterators in the :mod:`itertools` 
module:
        indices = sorted(random.choices(range(n), k=r))
        return tuple(pool[i] for i in indices)
 
+   def random_derangement(iterable):
+       "Choose a permutation where no element is in its original position."
+       seq = tuple(iterable)
+       if len(seq) < 2:
+           raise ValueError('derangments require at least two values')
+       perm = list(seq)
+       while True:
+           random.shuffle(perm)
+           if all(p != q for p, q in zip(seq, perm)):
+               return tuple(perm)
+
 The default :func:`.random` returns multiples of 2⁻⁵³ in the range
 *0.0 ≤ x < 1.0*.  All such numbers are evenly spaced and are exactly
 representable as Python floats.  However, many other representable

_______________________________________________
Python-checkins mailing list -- [email protected]
To unsubscribe send an email to [email protected]
https://mail.python.org/mailman3//lists/python-checkins.python.org
Member address: [email protected]

Reply via email to