On Sun, Aug 2, 2020 at 8:05 PM <raymond.hettinger@gmail.com> wrote:
FWIW, we've already documented a clean way to do it, https://docs.python.org/3/library/random.html#random.shuffle , "To shuffle an immutable sequence and return a new shuffled list, use sample(x, k=len(x)) instead."
one downside of this is that it won't work on a non-sized iterable -- but I suppose that's not really an important use-case. It Is a use case, though, 'cause while a shuffled collection is going to be sized by definition, the source could be a generator or some other non-sized iterable. But not hard to "realize" the iterable first by making it a list or tuple. My other question was about performance. Without looking at the code, I thought it *might* be faster to shuffle than build up a list with multiple samples. but in profiling, the sample version is only about 30% slower. (for this one example :-) ) In [13]: def shuffled_1(it): ...: result = list(it) ...: random.shuffle(result) ...: return result In [14]: def shuffled_2(it): ...: return random.sample(it, k=len(it)) In [15]: %timeit shuffled_1(population) 3.71 ms ± 30.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) In [16]: %timeit shuffled_2(population) 4.23 ms ± 23.9 µs per loop (mean ± std. dev. of 7 runs, 100 loops each) where: In [17]: population Out[17]: range(0, 10000) So yeah, this is a fine solution. -CHB -- Christopher Barker, PhD Python Language Consulting - Teaching - Scientific Software Development - Desktop GUI and Web Development - wxPython, numpy, scipy, Cython