2

There are quite a few questions on stack overflow regarding the random.shuffle method of the random module.

Something that irks me about shuffle is that it shuffles in-place rather than returning a shuffled copy.

Note that shuffle works in place, and returns None.

Therefore expressions like

for index, (parent1, parent2) in enumerate(zip(sorted(population)[::2], shuffle(population)[1::2])):

don't work. Writing it with a side effect seems unnecessarily verbose:

other_half = population[1::2]
random.shuffle(other_half)
for index, (parent1, parent2) in enumerate(zip(sorted(population)[::2], other_half):

What's a pythonic way of functionally shuffling a list?

Sebastian Wozny
  • 16,943
  • 7
  • 52
  • 69

2 Answers2

2

A good alternative would be random.sample with k being the len of the list:

import random

li = [1, 2, 3, 4, 5]

for _ in range(4):  # showing we get a new, 'shuffled' list
    print(random.sample(li, len(li)))

# [5, 2, 3, 1, 4]
# [1, 5, 4, 3, 2]
# [4, 2, 5, 1, 3]
# [4, 2, 3, 5, 1]
DeepSpace
  • 78,697
  • 11
  • 109
  • 154
  • I like this approach. I would like to know if there are any reasonable alternatives. In my opinion the `sample` approach obfuscates the intent a little. – Sebastian Wozny Nov 06 '17 at 11:58
  • 2
    @SebastianWozny I think that's debatable. If you pick `x` random elements from a list with `x` elements then you are essentially shuffling the list. However, you may always wrap it with your own function with your own name. – DeepSpace Nov 06 '17 at 12:03
2

This looks like a duplicate of this question

The accepted answer was

shuffled = sorted(x, key=lambda k: random.random())
stx101
  • 271
  • 1
  • 7
  • It does indeed look like a duplicate. I find the title misleading on the other question, also because it didn't turn up in my google search for the problem. Maybe there is value of keeping the question here with your link. – Sebastian Wozny Nov 06 '17 at 12:11