向.txt文件的每一行添加(非重复)随机数

问题描述 投票:1回答:2

我正在创建一个.txt文件,该团队中有四名士兵,按照功绩排名。士兵不给自己定级。

我有以下代码:

import itertools

# create a list of 4 soldiers
numSoldiers=4
soldiers = []
for i in range(1,numSoldiers+1):
    soldiers.append('soldier'+str(i))

# create list of all permutations of 2 soldiers
perms = list(itertools.permutations(soldiers, 2))

# list of possible rankings (soldier does not rank himself/herself)
possRanks = list(range(1,len(soldiers)))

# create the edgelist .txt file with randomized rankings
open('peerRankingsEdgelist.txt', 'w').close() #delete contents of .txt file at the start

file = open('peerRankingsEdgelist.txt', 'w')

for i in perms:
    file.write(i[0] + ', ' + i[1] + '\n')

file.close() #close file

将在.txt文件中产生以下输出:

soldier1, soldier2
soldier1, soldier3
soldier1, soldier4
soldier2, soldier1
soldier2, soldier3
soldier2, soldier4
soldier3, soldier1
soldier3, soldier2
soldier3, soldier4
soldier4, soldier1
soldier4, soldier2
soldier4, soldier3

对于三行的每组(以相同的soldier开头的行的集合),我想添加一个来自possRanks的随机排名,其中possRanks = [1, 2, 3]。问题是我不能完全随机化它,因为这样排名可能会重复。例如,soldier1可能将soldier2soldier3的排名都定为1,这是我无法获得的。

正确的示例输出如下:

soldier1, soldier2, 3
soldier1, soldier3, 1
soldier1, soldier4, 2
soldier2, soldier1, 1
soldier2, soldier3, 2
soldier2, soldier4, 3
soldier3, soldier1, 2
soldier3, soldier2, 1
soldier3, soldier4, 3
soldier4, soldier1, 1
soldier4, soldier2, 2
soldier4, soldier3, 3

[此处,soldier1soldier2的值为3,将soldier3的值为1,将soldier4的值为2

python random text itertools edge-list
2个回答
1
投票

以您的文件为例data.txt

soldier1, soldier2
soldier1, soldier3
soldier1, soldier4
soldier2, soldier1
soldier2, soldier3
soldier2, soldier4
soldier3, soldier1
soldier3, soldier2
soldier3, soldier4
soldier4, soldier1
soldier4, soldier2
soldier4, soldier3

[我们可以使用itertools grouper recipe读取N个大小的文件,用possRanks随机排列random.shuffle,然后按random.shuffle每个组,每个随机排列的等级。然后,我们可以打开一个要写入的新文件,例如zip

zip

每次您执行上述操作时,都会在output.txt中随机写入等级排名:

from random import shuffle
from itertools import zip_longest

def grouper(iterable, n, fillvalue=None):
    "Collect data into fixed-length chunks or blocks"
    # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx"
    args = [iter(iterable)] * n
    return zip_longest(*args, fillvalue=fillvalue)

possRanks = [1, 2, 3]

with open("data.txt") as f, open("output.txt", mode="w") as o:
    for line in grouper(map(str.strip, f), len(possRanks), ''):
        shuffle(possRanks)
        for group, rank in zip(line, possRanks):
            o.write(f"{group}, {rank}\n")

0
投票

这里是仅使用output.txt的另一种方法,它可能更易于解析;

soldier1, soldier2, 2
soldier1, soldier3, 1
soldier1, soldier4, 3
soldier2, soldier1, 1
soldier2, soldier3, 3
soldier2, soldier4, 2
soldier3, soldier1, 2
soldier3, soldier2, 3
soldier3, soldier4, 1
soldier4, soldier1, 3
soldier4, soldier2, 1
soldier4, soldier3, 2

所以我唯一更改的部分在这里:

enum

基本上,我正在使用import itertools import random # create a list of 4 soldiers numSoldiers=4 soldiers = [] for i in range(1,numSoldiers+1): soldiers.append('soldier'+str(i)) # create list of all permutations of 2 soldiers perms = list(itertools.permutations(soldiers, 2)) # list of possible rankings (soldier does not rank himself/herself) possRanks = list(range(1,len(soldiers))) # create the edgelist .txt file with randomized rankings open('peerRankingsEdgelist.txt', 'w').close() #delete contents of .txt file at the start file = open('peerRankingsEdgelist.txt', 'w') for num, i in enumerate(perms): if num % len(possRanks) == 0: shuffled_ranks = possRanks.copy() random.shuffle(shuffled_ranks) random_rank = str(shuffled_ranks.pop()) line = (i[0]) + ', ' + i[1] + ',' + random_rank + '\n' file.write(line) file.close() #close file 来计算每次迭代,并且只创建每for num, i in enumerate(perms): if num % len(possRanks) == 0: shuffled_ranks = possRanks.copy() random.shuffle(shuffled_ranks) random_rank = str(shuffled_ranks.pop()) line = (i[0]) + ', ' + i[1] + ',' + random_rank + '\n' 次迭代的数量enumerate的新随机列表,其中possRanks等于x。然后,我们只从列表中弹出每个项目,基本上每x次迭代就用尽该列表,并在用尽后创建一个新列表。

© www.soinside.com 2019 - 2024. All rights reserved.