2015-11-24 20 views
1

我想問如何洗牌,也許在一個while循環,直到所有的名單是完全不同的(如數獨)?蟒蛇,洗牌,直到列表完全不同

#lists you want to shuffle 
s1 = [1, 2, 3, 4] 
s2 = [1, 2, 3, 4] 
s3 = [1, 2, 3, 3] 
s4 = [1, 2, 3, 4] 

def mid_generator(): 

    while True: 
     random.shuffle(s1) 
     random.shuffle(s2) 
     random.shuffle(s3) 
     random.shuffle(s4) 

     # if ... all lists are different...: 
      #break 

    return s1, s2, s3, s4 

所以這個數字僅僅是一個在第i行第j列時間:

s1 = [3, 1, 2, 4] 
s2 = [4, 2, 1, 3] 
s3 = [2, 4, 3, 1] 
s4 = [1, 3, 4, 2] 

,如果我嘗試長if語句與如果s1 [0] = S2 [0] .. ..輸出是錯誤的。 也許你可以幫助我。

+0

您是否試圖生成隨機[拉丁方塊](https://en.wikipedia.o RG /維基/ Latin_square)? [這似乎是一個難題](http://math.stackexchange.com/questions/63131/generate-random-latin-squares),如果你想統一。 – user2357112

+0

不是直接。我想獲得不同的列表,如在數獨遊戲中。 –

+0

數獨網格甚至更受限制,你的問題甚至沒有提及。你真的需要在你的問題中說出類似的東西。 – user2357112

回答

1

這仍然是一個效率低下的算法,因爲它基於您的原始代碼,但您可以將每個位置的元素放入集合中並檢查它們的長度; len({1, 2, 3, 3})3,因爲只有3個獨特的元素:

import random 

#lists you want to shuffle 
s1 = [1, 2, 3, 4] 
s2 = [1, 2, 3, 4] 
s3 = [1, 2, 3, 4] 
s4 = [1, 2, 3, 4] 

def mid_generator(): 

    while True: 
     random.shuffle(s1) 
     random.shuffle(s2) 
     random.shuffle(s3) 
     random.shuffle(s4) 

     test0 = {s1[0], s2[0], s3[0], s4[0]} 
     test1 = {s1[1], s2[1], s3[1], s4[1]} 
     test2 = {s1[2], s2[2], s3[2], s4[2]} 
     test3 = {s1[3], s2[3], s3[3], s4[3]} 

     if len(test0) == len(test1) == len(test2) == len(test3) == 4: 
      break 

    return s1, s2, s3, s4 

實例交互輸出:

>>> mid_generator() 
([3, 4, 2, 1], [1, 2, 4, 3], [4, 3, 1, 2], [2, 1, 3, 4]) 
+0

首先,我感謝您的幫助!但我仍然有一個問題,有時我生成一個列中具有相同數字的代碼。 –

+0

@MartinM你是什麼意思?上面的代碼應該可以工作。 – Galax

+0

我用新代碼替換了代碼,現在它可以工作!你幫了我很多! –

-1

這將工作 - 但它不是最優的 - 但是,如果檢查將工作

def mid_generator(): 

    while True: 
     random.shuffle(s1) 
     random.shuffle(s2) 
     random.shuffle(s3) 
     random.shuffle(s4) 

     if not (s1 == s2 or s1 == s3 or s1 == s4 or s2 == s3 or s2 == s4 or s3 == s4): 
      break 

    return s1, s2, s3, s4 
+0

爲什麼投票 - 它工作正常?他沒有對拉丁廣場做任何說明 - 所以這個解決方案是一個正確的答案,不要作出不能證明的暗示 – gkusner

+0

沒有在尋找4個列表來簡單地做出不同的排列,他正在尋找每個數字在每個清單中的不同位置 - [拉丁廣場](https://en.wikipedia.org/wiki/Latin_square) – Galax

+0

不在原始問題 – gkusner

1

這是非常醜陋的,但如果你仔細地正確地比較每個列表中的每個列與每個列表,長列表and報表工作太細:

def mid_generator(): 

    while True: 
     random.shuffle(s1) 
     random.shuffle(s2) 
     random.shuffle(s3) 
     random.shuffle(s4) 

     if ( s1[0] != s2[0] and s1[0] != s3[0] and s1[0] != s4[0] 
      and s2[0] != s3[0] and s2[0] != s4[0] and s3[0] != s4[0] 
      and s1[1] != s2[1] and s1[1] != s3[1] and s1[1] != s4[1] 
      and s2[1] != s3[1] and s2[1] != s4[1] and s3[1] != s4[1]     
      and s1[2] != s2[2] and s1[2] != s3[2] and s1[2] != s4[2] 
      and s2[2] != s3[2] and s2[2] != s4[2] and s3[2] != s4[2]     
      and s1[3] != s2[3] and s1[3] != s3[3] and s1[3] != s4[3] 
      and s2[3] != s3[3] and s2[3] != s4[3] and s3[3] != s4[3]): 
      break 
    return s1, s2, s3, s4 
+0

啊再次感謝你!我也嘗試了一個很長的if語句,但正如你所說的,你必須非常小心,對於我來說,使用long if語句是非常困難的。 –

+0

是的,即使是帶有集合的版本也有點脆弱,因爲輸入其中一個數字很容易。如果你看到廣義版本有多短,你可能會認爲這是最好的方法;) – Galax

1

只是爲了完整性,這裏的任意列表長度的通用版本:

def mid_generator(n): 
    s = [list(range(1, n+1)) for x in range(n)] 
    while True: 
     for x in s: 
      random.shuffle(x) 
     for i in range(n): 
      test = {s[j][i] for j in range(n)} 
      if len(test) != n: 
       break 
     else: 
      return s 
    return None # never hit 

互動:

>>> mid_generator(1) 
[[1]] 
>>> mid_generator(2) 
[[1, 2], [2, 1]] 
>>> mid_generator(3) 
[[1, 3, 2], [3, 2, 1], [2, 1, 3]] 
>>> mid_generator(4) 
[[2, 4, 1, 3], [4, 2, 3, 1], [1, 3, 2, 4], [3, 1, 4, 2]] 
>>> mid_generator(5) 
[[4, 5, 2, 1, 3], [1, 2, 3, 5, 4], [3, 4, 5, 2, 1], [5, 1, 4, 3, 2], [2, 3, 1, 4, 5]] 
>>> mid_generator(6) 

(仍在等待...)