从列表长度不同的列表中获取加权随机值

时间:2019-10-23 19:17:52

标签: python list random nested-lists

我需要创建一个新列表,该列表具有从列表列表中拉出的随机值,其中辅助列表的长度可能不同。

此外,我需要考虑到,例如,如果二级列表之一大于其余二级列表,则从所述列表中获取值的概率必须高于较短的二级列表。随机值可以选择一次以上,这意味着选择后我不必将其从列表中删除。

我能够创建列表列表,每个辅助列表对应一个区域,其内容对应于随机生成的客户代码,到目前为止,效果很好。但是,当我使用random.choice()函数创建具有随机值的新列表时,我从可用列表中获得了x数量的随机列表,而不是从ALL列表中选取的随机值。

thislist = []

# So I have my blank list and I am ready to populate the list with, 
# in this case, 10 random values from the list of lists named 'codigo_cliente'

for i in range(10):
    thislist.append(random.choice(codigo_cliente))

在此示例中,共有30个客户端的客户端代码:

客户代码:

[['A-336', 'A-437', 'A-720', 'A-233', 'A-499'], 
 ['B-664', 'B-133', 'B-267', 'B-421', 'B-553', 'B-910', 'B-792', 'B-719', 'B-550', 'B-946'], 
 ['C-755', 'C-533', 'C-596', 'C-877', 'C-400', 'C-354', 'C-471', 'C-169', 'C-329', 'C-318', 'C-550', 'C-422', 'C-251', 'C-852', 'C-309']]

我得到以下输出,这不是我想要的:

这是所选客户的随机列表:

[['B-664', 'B-133', 'B-267', 'B-421', 'B-553', 'B-910', 'B-792', 'B-719', 'B-550', 'B-946'], 
 ['A-336', 'A-437', 'A-720', 'A-233', 'A-499'], 
 ['C-755', 'C-533', 'C-596', 'C-877', 'C-400', 'C-354', 'C-471', 'C-169', 'C-329', 'C-318', 'C-550', 'C-422', 'C-251', 'C-852', 'C-309'], 
 ['A-336', 'A-437', 'A-720', 'A-233', 'A-499'], 
 ['B-664', 'B-133', 'B-267', 'B-421', 'B-553', 'B-910', 'B-792', 'B-719', 'B-550', 'B-946'], 
 ['C-755', 'C-533', 'C-596', 'C-877', 'C-400', 'C-354', 'C-471', 'C-169', 'C-329', 'C-318', 'C-550', 'C-422', 'C-251', 'C-852', 'C-309'], 
 ['C-755', 'C-533', 'C-596', 'C-877', 'C-400', 'C-354', 'C-471', 'C-169', 'C-329', 'C-318', 'C-550', 'C-422', 'C-251', 'C-852', 'C-309'], 
 ['C-755', 'C-533', 'C-596', 'C-877', 'C-400', 'C-354', 'C-471', 'C-169', 'C-329', 'C-318', 'C-550', 'C-422', 'C-251', 'C-852', 'C-309'], 
 ['B-664', 'B-133', 'B-267', 'B-421', 'B-553', 'B-910', 'B-792', 'B-719', 'B-550', 'B-946'], 
 ['A-336', 'A-437', 'A-720', 'A-233', 'A-499']]

相反,我应该得到类似以下的内容:

thislist = ['A-336', 'B-553', 'C-596', 'B-910', 'C-251', 'C-329', 'B-910', 'A-437', 'B-946', 'C-251'] 

# Notice how there are more values with the "C" prefix from the larger secondary list,
# than values with the A or B prefixes from the smaller secondary lists.

3 个答案:

答案 0 :(得分:1)

加权选择

random.choices(population, weights, k)列出了权重列表,供您随机选择。因此,您可以将其子列表的长度作为权重:

weights = [len(c) for c in codigo_cliente]

,然后让它为您选择一个子列表(您也可以使用k=10告诉它选择一个子列表10次)。然后,您可以从每个子列表中选择一个任意列表元素:

thislist = [random.choice(c) for c in random.choices(codigo_cliente, weights=weights, k=10)]

您也可以将其组合在一起以获得单线解决方案:

thislist = [random.choice(c) for c in random.choices(codigo_cliente, weights=[len(c) for c in codigo_cliente], k=10)
]

参考:A weighted version of random.choice

平头清单

如果您负担得起额外的存储空间,则可以展平列表并在展平的列表上进行选择,如下所示:

import random
import itertools

codigo_cliente = [['A-336', 'A-437', 'A-720', 'A-233', 'A-499'],
                  ['B-664', 'B-133', 'B-267', 'B-421', 'B-553', 'B-910', 'B-792', 'B-719', 'B-550', 'B-946'],
                  [
                      'C-755', 'C-533', 'C-596', 'C-877', 'C-400', 'C-354', 'C-471', 'C-169', 'C-329', 'C-318',
                      'C-550', 'C-422', 'C-251', 'C-852', 'C-309'
                  ]]
thislist = []
temp = list(itertools.chain.from_iterable(codigo_cliente))

for i in range(10):
    thislist.append(random.choice(temp))

print(thislist)

可以使用多种方法来平整嵌套列表:How to make a flat list out of list of lists?

答案 1 :(得分:1)

您不是从这些嵌套列表中选择随机项目,而是完整的嵌套列表。

首先获取随机嵌套列表,然后随机选择项目

for i in range(10):
    rand_list = random.choice(codigo_cliente)
    thislist.append(random.choice(rand_list))

答案 2 :(得分:1)

在将random.choices()参数设置为列表长度的情况下使用weights。这将根据列表的长度选择列表。然后使用random.choice()从每个列表中选择一个元素。 k是要选择的项目数:

from random import choice, choices

w = [len(d) for d in codigo_cliente]
[choice(lst) for lst in choices(codigo_cliente, weights=w, k=10)]

示例输出:

['C-400', 'C-596', 'B-553', 'C-471', 'B-133',
 'C-596', 'B-133', 'A-499', 'C-471', 'C-400']