向 .txt 文件的每一行添加(非重复)随机数
Adding (non-repeating) Random Numbers to Each Line of .txt File
我正在创建一个 .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, shuffle possRanks
with random.shuffle
, then zip
每个组和每个打乱的排名来读取 N 个大小的块中的文件。然后我们可以打开一个新文件来写入,例如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
来计算每次迭代,并且只创建
每 x
次迭代的新随机列表 possRanks
,其中 x
等于 len of possRanks
。
然后我们只是从列表中弹出每个项目,基本上每 x
次迭代耗尽列表,并在耗尽后创建一个新列表。
我正在创建一个 .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, shuffle possRanks
with random.shuffle
, then zip
每个组和每个打乱的排名来读取 N 个大小的块中的文件。然后我们可以打开一个新文件来写入,例如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
来计算每次迭代,并且只创建
每 x
次迭代的新随机列表 possRanks
,其中 x
等于 len of possRanks
。
然后我们只是从列表中弹出每个项目,基本上每 x
次迭代耗尽列表,并在耗尽后创建一个新列表。