2012-05-10 65 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相同的行中,但是我甚至不知道是否这是可能的,而且我现在非常急于关心这个问题,所以我只需手工检查并纠正。非常感谢你! –

相关问题