我正在创建一个.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
可能将soldier2
和soldier3
的排名都定为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
[此处,soldier1
将soldier2
的值为3
,将soldier3
的值为1
,将soldier4
的值为2
。
以您的文件为例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")
这里是仅使用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
次迭代就用尽该列表,并在用尽后创建一个新列表。