2012-05-10 66 views
1

我一直在工作幾個月,開啓和關閉腳本,以便在文本文件中隨機播放列表。我是Python的初學者(這是我理解的唯一一種語言),過了一段時間,我設法想出了幾行代碼,這些代碼完成了我需要的東西。Python - 用約束對一個列表進行隨機排序

我擁有的輸入文件是一個選項卡式列表。它具有每行5個字,但這樣看起來的例子更清楚我會讓它的數字:現在

01 02 03 04 05 
06 07 08 09 10 
11 12 13 14 15 
16 17 18 19 20 
21 22 23 24 25 

,經過幾次努力和SO用戶的工作,數額巨大,我已經成功地洗牌這些元素,以便它們不會出現在與原始「合作伙伴」相同的行中。這是我正在使用的代碼:

import csv,StringIO 
import random 
from random import shuffle 

datalist = open('lista.txt', 'r') 
leyendo = datalist.read() 
separando = csv.reader(StringIO.StringIO(leyendo), delimiter = '\t') 
macrolist = list(separando) 

l = [group[:] for group in macrolist] 
random.shuffle(l) 
nicendone = [] 
prev_i = -1 
while any(a for a in l): 
    new_i = max(((i,a) for i,a in enumerate(l) if i != prev_i), key=lambda x: len(x[1]))[0] 
    nicendone.append(l[new_i].pop(random.randint(0, len(l[new_i]) - 1))) 
    prev_i = new_i 

with open('randolista.txt', 'w') as newdoc: 
    for i, m in enumerate(nicendone, 1): 
     newdoc.write(m + [', ', '\n'][i % 5 == 0]) 

datalist.close() 

這樣做的工作,但我真正需要的是一點複雜。我需要按照以下限制對列表進行隨機整理:

  1. 第一列和第二列中的詞應該在其自己的列中進行混洗。
  2. 新的隨機列表應該沒有兩個元素再次出現在同一行中。

我想什麼得到的是類似以下內容:

01 17 25 19 13 
16 22 13 03 20 
etc 

因此,在第一和第二列項只屬於自己的欄目內洗牌,沒有兩個項目是在輸出中同一行中的同一行。我意識到在一個5行的例子中,這個最後的約束不斷被打破,但真正的輸入文件有100行。

我真的不知道如何開始這樣做。我的編程能力是有限的,但問題是,我甚至不能爲它創建一個僞代碼。我怎樣才能讓Python識別前兩列的元素,以便只將它們垂直拖動?

在此先感謝

+0

不要讓'1 2 3 4 5'到'1 7 43 52 15'部分。你能否用類似於輸入和預期輸出的5行示例來更新問題? –

+0

好的,你的意思是編輯原始問題。對不起。 –

回答

0

洗牌前兩列以這樣的方式,曾經是在同一行中的兩個值不會出現在同一行可以通過隨機數調換的列來完成。例如:您可以向下推第一列20行,向下推第二列10行,其中20和10是小於行數的隨機整數。

是隨機化的前兩列的樣本代碼:從隨機導入樣本

text = \ 
"""a b c d e 
f g h i j 
k l m n o 
p q r s t""" 

# Translate file to matrix (list of lists) 
matrix = map(lambda x: x.split(" "), text.split("\n")) 

# Determine height and height of matrix 
height = len(matrix) 
width = len(matrix[0]) 

# Choose two (unique) numbers for transposing the first two columns 
transpose_list = sample(xrange(0, height), 2) 

# Now build a new matrix, transposing only the first two 
# columns. 
new_matrix = [] 
for y in range(0, height): 
    row = [] 
    for x in range(0, 2): 
     transpose = (y + transpose_list[x]) % height 
     row.append(matrix[transpose][x]) 

    for x in range(2, width): 
     row.append(matrix[y][x]) 

    new_matrix.append(row) 

# And create a list again 
new_text = "\n".join(map(lambda x: " ".join(x), new_matrix)) 
print new_text 

這導致類似:

a l c d e 
f q h i j 
k b m n o 
p g r s t 

如果我理解你正確後,您已經有了一個隨機化表的其餘部分的算法?

我希望這有任何幫助:-)。

Wout

+0

你是個天才,先生。這幾乎是我所需要的!列表的其餘部分可以用我已有的算法隨機化。理想的情況是爲了確保c,d和e(在這個例子中)不會出現在一起(它已經)或者在與a或b相同的行中,但是我甚至不知道是否這是可能的,而且我現在非常急於關心這個問題,所以我只需手工檢查並糾正。非常感謝你! –

相關問題