1

私は、テキストファイル内のリストをシャッフルするためのスクリプトのオンとオフを問わず、数か月間取り組んできました。私はPython(私が少し理解している唯一の言語)の初心者であり、しばらくして、必要なことを実行する数行のコードを思い付くことができました。

私が持っている入力ファイルはタブ付きリストです。1行あたり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. 1列目と2列目の単語は、それぞれの列内でのみシャッフルする必要があります。
  2. 新しいランダム化リストには、同じ行に2つの要素が再び表示されないようにする必要があります。

私が取得したいのは次のようなものです:

01 17 25 19 13
16 22 13 03 20
etc

そのため、1列目と2列目の項目はそれぞれの列内でのみシャッフルされ、入力の同じ行にあった2つの項目が出力の同じ行に存在することはありません。5行の例では、この最後の制約は常に破られていますが、実際の入力ファイルには100行あります。

私は本当にこれを始める方法さえ知りません。私のプログラミング能力は限られていますが、問題は、そのための擬似コードを思い付くことさえできないということです。Pythonに最初の2つの列の要素を識別させて、それらを垂直方向にのみシャッフルするようにするにはどうすればよいですか?

前もって感謝します

4

1 に答える 1

0

同じ行にあった2つの値が同じ行に表示されないように、最初の2つの列をシャッフルすることは、列を乱数で置き換えることによって実現できます。たとえば、最初の列を20行下に、2番目の列を10行下にプッシュできます。ここで、20と10は、行数よりも少ないランダムな整数です。

最初の2つの列をランダム化するサンプルコード:ランダムインポートサンプルから

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

于 2012-05-10T11:40:51.820 に答える