2

I know how to shuffle a list of elements. But hos should I do if I want to shuffle all the elements between two specific elements.

import random
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
random.shuffle(x)
print(x)

I tried following way, but it produce "None".

import random
x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
random.shuffle(x[2:5]) # need an output like this e.g: [1, 2, 4, 5, 3, 6, 7, 8, 9, 10]
print(x)

But it didnt work. Thanks for the help.

Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219
Mass17
  • 1,555
  • 2
  • 14
  • 29

2 Answers2

3

shuffle works in-place, so you need to take a slice of your list, shuffle it, and then slice-reassign to the original list.

>>> from random import shuffle
>>> 
>>> x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

Create a shuffled list shuffled.

>>> shuffle_range = slice(2, 5)
>>> shuffled = x[shuffle_range]
>>> shuffle(shuffled)

Reassign the shuffled part to a slice of the original list:

>>> x[shuffle_range] = shuffled
>>> 
>>> x
[1, 2, 4, 5, 3, 6, 7, 8, 9, 10]

I created the slice(2, 5) object in order to not repeat myself typing the indices.

x is mutated in-place in this approach, just like you would expect from an ordinary shuffle-operation.

timgeb
  • 76,762
  • 20
  • 123
  • 145
3

shuffle works in place. So what happens is that your list slice x[2:5] is shuffled, then discarded as it has no reference left.

You'd have to do:

part = x[2:5]
random.shuffle(part)
x = x[:2] + part + x[5:]

This naïve approach which recreates a copy of x. If x is huge and you just shuffle a small part of it, the memory overhead is too much. Commenters suggested to replace the last line by a better slice assignment:

x[2:5] = part
Jean-François Fabre
  • 137,073
  • 23
  • 153
  • 219