在下一个子列表中添加新元素,具体取决于是否已添加(还涉及字典问题)python



堆栈溢出社区:

我正在尝试创建一个子列表列表,并基于另一个列表值的随机采样进行循环;并且每个子列表都有一个限制,即不具有重复或已经添加到先前子列表中的值。

举个例子,我有一个主要列表:

[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
#I get:
[[1,13],[4,1],[8,13]]
#I WANT:
[[1,13],[4,9],[8,14]]          #(no duplicates when checking previous sublists)

我认为它会起作用的真正代码如下(作为草案(:

matrixvals=list(matrix.index.values)  #list where values are obtained
lists=[[]for e in range(0,3)]         #list of sublists that I want to feed
vls=[]                                #stores the values that have been added to prevent adding them again
for e in lists:                       #initiate main loop
for i in range(0,5):              #each sublist will contain 5 different random samples
x=random.sample(matrixvals,1) #it doesn't matter if the samples are 1 or 2
if any(x) not in vls:         #if the sample isn't in the evaluation list
vls.extend(x)
e.append(x)
else:             #if it IS, then do a sample but without those already added values (line below)
x=random.sample([matrixvals[:].remove(x) for x in vls],1)
vls.extend(x)
e.append(x)

print(lists)
print(vls)

它没有起作用,因为我得到了以下信息:

[[[25], [16], [15], [31], [17]], [[4], [2], [13], [42], [13]], [[11], [7], [13], [17], [25]]]
[25, 16, 15, 31, 17, 4, 2, 13, 42, 13, 11, 7, 13, 17, 25]

正如你所看到的,数字13重复了3次,我不明白为什么

我想要:

[[[25], [16], [15], [31], [17]], [[4], [2], [13], [42], [70]], [[11], [7], [100], [18], [27]]]
[25, 16, 15, 31, 17, 4, 2, 13, 42, 70, 11, 7, 100, 18, 27]   #no dups

此外,有没有一种方法可以将sample.random结果转换为值而不是列表?(获取(:

[[25,16,15,31,17]], [4, 2, 13, 42,70], [11, 7, 100, 18, 27]]

此外,现实中的最终结果不是一个子列表列表,实际上是一个字典(上面的代码是解决dict问题的草案(,有没有办法在dict中获得以前的方法?用我现在的代码,我得到了下一个结果:

{'1stkey': {'1stsubkey': {'list1': [41,
40,
22,
28,
26,
14,
41,
15,
40,
33],
'list2': [41, 40, 22, 28, 26, 14, 41, 15, 40, 33],
'list3': [41, 40, 22, 28, 26, 14, 41, 15, 40, 33]},
'2ndsubkey': {'list1': [21,
7,
31,
12,
8,
22,
27,...}

而不是这个结果,我想要以下内容:

{'1stkey': {'1stsubkey': {'list1': [41,40,22],
'list2': [28, 26, 14],
'list3': [41, 15, 40, 33]},
'2ndsubkey': {'list1': [21,7,31],
'list2':[12,8,22],
'list3':[27...,...}#and so on 

有没有办法同时解决列表和dict问题?任何帮助都将不胜感激;即使只有列表问题,我也能取得一些进展

感谢所有

我意识到您可能更感兴趣的是找出为什么您的特定方法不起作用。但是,如果我已经理解了你想要的行为,我可能会提供一个替代的解决方案。在发布我的答案后,我会看看你的尝试。

random.sample允许您从population(集合、列表等(中采样k数量的项目。如果集合中没有重复的元素,则保证您的随机样本中没有重复:

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]
>>> 

不管你运行这个片段多少次,你的随机样本中永远不会有重复的元素。这是因为random.sample不会生成随机对象,它只是随机挑选集合中已经存在的项目。例如,这与从一副牌中随机抽取卡片或抽取彩票号码时采用的方法相同。

在您的情况下,pool是可以从中选择样本的可能唯一数字池。您想要的输出似乎是一个由三个列表组成的列表,其中每个子列表中都有两个样本。与其三次调用random.sample,每个子列表一次,不如用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))

EDIT-刚刚意识到你实际上并不想要列表,而是想要一本字典。更像这样的东西?对不起,我痴迷于发电机,这并不容易阅读:

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]}}}
>>> 

最新更新