Python - 使用约束来改组列表

时间:2012-05-10 09:48:07

标签: python constraints shuffle

我已经在一个脚本上工作了几个月,打开和关闭了一个文本文件中的列表。我是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. 新的随机列表应该没有两个元素再次出现在同一行。
  3. 我想得到的是以下内容:

    01 17 25 19 13
    16 22 13 03 20
    etc
    

    因此,第一列和第二列中的项目仅在其自己的列中进行混洗,并且输出中同一行中没有两个项目位于输入的同一行中。我在5行示例中意识到这最后一个约束经常被破坏,但真正的输入文件有100行。

    我真的不知道如何开始这样做。我的编程能力有限,但问题是我甚至无法想出它的伪代码。如何让Python识别前两列的元素,以便它只是垂直地对它们进行混洗?

    提前致谢

1 个答案:

答案 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的