我知道你可能更感兴趣的是找出你的特定方法不起作用的原因。然而,如果我了解你想要的行为,我也许能提供一个替代的解决方案。在发布我的答案后,我会看看你的尝试。
random.sample
让你取样
k
来自某个应用程序的项目数
population
(收集、列表等等。)如果集合中没有重复元素,则保证随机样本中没有重复:
from random import sample
pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
num_samples = 4
print(sample(pool, k=num_samples))
可能的输出:
[9, 11, 8, 7]
>>>
不管你运行这个片段多少次,你的随机样本中永远不会有重复的元素。这是因为
随机的样品
它不会生成随机对象,只是随机选取集合中已经存在的项目。例如,当你从一副卡片中随机抽取卡片,或者抽取彩票号码时,你会采用同样的方法。
就你而言,
pool
是可以从中选择样本的唯一编号池。您想要的输出似乎是一个包含三个列表的列表,其中每个子列表中有两个样本。而不是打电话
随机的样品
三次,每个子列表一次,我们应该用
k=num_sublists * num_samples_per_sublist
:
from random import sample
pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
num_sublists = 3
samples_per_sublist = 2
num_samples = num_sublists * samples_per_sublist
assert num_samples <= len(pool)
print(sample(pool, k=num_samples))
可能的输出:
[14, 10, 1, 8, 6, 3]
>>>
好的,我们有六个样本,而不是四个。还没有子列表。现在,您可以简单地将这个包含六个样本的列表拆分为三个子列表,每个子列表包含两个样本:
from random import sample
pool = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]
num_sublists = 3
samples_per_sublist = 2
num_samples = num_sublists * samples_per_sublist
assert num_samples <= len(pool)
def pairwise(iterable):
yield from zip(*[iter(iterable)]*samples_per_sublist)
print(list(pairwise(sample(pool, num_samples))))
可能的输出:
[(4, 11), (12, 13), (8, 15)]
>>>
或者如果你真的想要子列表,而不是元组:
def pairwise(iterable):
yield from map(list, zip(*[iter(iterable)]*samples_per_sublist))
编辑——刚刚意识到你其实并不想要一个列表,而是一本字典。像这样的吗?抱歉,我痴迷于发电机,这真的不容易读:
keys = ["1stkey"]
subkeys = ["1stsubkey", "2ndsubkey"]
num_lists_per_subkey = 3
num_samples_per_list = 5
num_samples = num_lists_per_subkey * num_samples_per_list
min_sample = 1
max_sample = 50
pool = list(range(min_sample, max_sample + 1))
def generate_items():
def generate_sub_items():
from random import sample
samples = sample(pool, k=num_samples)
def generate_sub_sub_items():
def chunkwise(iterable, n=num_samples_per_list):
yield from map(list, zip(*[iter(iterable)]*n))
for list_num, chunk in enumerate(chunkwise(samples), start=1):
key = f"list{list_num}"
yield key, chunk
for subkey in subkeys:
yield subkey, dict(generate_sub_sub_items())
for key in keys:
yield key, dict(generate_sub_items())
print(dict(generate_items()))
可能的输出:
{'1stkey': {'1stsubkey': {'list1': [43, 20, 4, 27, 2], 'list2': [49, 44, 18, 8, 37], 'list3': [19, 40, 9, 17, 6]}, '2ndsubkey': {'list1': [43, 20, 4, 27, 2], 'list2': [49, 44, 18, 8, 37], 'list3': [19, 40, 9, 17, 6]}}}
>>>