2016-12-06 72 views
6

Chciałbym losowo przetasować listę tak, aby każda zmienna na liście podczas jej losowania została umieszczona w nowym miejscu na liście.Python: Jak losowo przetasować listę, w której każda zmienna znajdzie się w nowym miejscu.

Co Jestem obecnie robi:

list = ['a', 'b','c', 'd']; 
random.shuffle(list) 

list 
['c','b','d','a'] 

Dzięki tej metodzie I przetasować listę, ale wciąż jest to możliwe, aby mieć zmienną kończy się w tym samym miejscu w tym przypadku „b”.

My pożądane wyjście

całkowicie tasuje lista

['c','a','d','b'] 

I wdzięczni za każdą pomoc. Jestem nowym użytkownikiem Pythona, ale daj mi znać, czy potrzebne są dalsze informacje.

+3

jak duża jest Twoja lista oczekiwać, aby być? z grubsza mówiąc. –

+0

@matiaselgart moja lista będzie zawierać 15 zmiennych. – Dre

+4

Po prostu notatka: Jeśli chcesz, aby każdy element był w prawdziwie losowej pozycji, odrzucanie aranżacji, które nie poruszają każdego elementu, faktycznie zmniejsza "losowość". Bardzo rzadko zdarza się, że sytuacja jest bardziej poprawna/bezpieczna, aby arbitralnie odrzucić dowolny przypadkowy układ; niedopuszczenie, by element utrzymywał tę samą pozycję, ujawnia więcej informacji niż pozwalanie na losowe losowanie. – ShadowRanger

Odpowiedz

4

Coś jak to powinien robić to, co chcesz:

import random 
import copy 

def super_shuffle(lst): 
    new_lst = copy.copy(lst) 
    random.shuffle(new_lst) 
    for old, new in zip(lst, new_lst): 
     if old == new: 
      return super_shuffle(lst) 

    return new_lst 

Przykład:

In [16]: super_shuffle(['a', 'b', 'c']) 
Out[16]: ['b', 'c', 'a'] 
+0

Uruchomiłem ten kod z listą wejściową ["a", "b", "c", "d", "e", "f"] wiele razy, czasami otrzymując nową listę z powrotem z elementami w tej samej pozycji . –

+1

To chyba najlepsze podejście. Średnio około 1/e (około 37%) permutacji są zakłóceniami, prawie niezależnie od rozmiaru listy, więc nigdy nie musisz przechodzić przez zbyt wiele prób zanim otrzymasz trafienie. –

+0

@John Coleman Dzięki. Zaktualizowano. – Jack