1

我已经在一个脚本上工作了几个月,断断续续地处理文本文件中的列表。我是 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 识别前两列的元素,使其仅垂直打乱它们?

提前致谢

4

1 回答 1

0

可以通过用随机数对列进行转置来实现前两列的混洗,以使曾经在同一行上的两个值不会出现在同一行上。例如:您可以将第一列向下推 20 行,将第二列向下推 10 行,其中 20 和 10 是小于行数的随机整数。

将前两列随机化的示例代码:from random import sample

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

如果我理解你的帖子正确,你已经有一个算法来随机化表格的其余部分?

我希望这有任何帮助:-)。

伍特

于 2012-05-10T11:40:51.820 回答