Получение взвешенных случайных значений из списка списков с различными длинами списков - PullRequest
0 голосов
/ 23 октября 2019

Мне нужно создать новый список со случайными значениями, извлеченными из списка списков, где вторичные списки могут иметь разную длину.

Кроме того, я должен принять во внимание, что, например, если один из вторичных списков больше остальных, тогда вероятности получения значения из указанного списка должны быть выше, чем у более короткого вторичногосписки. Случайные значения могут быть выбраны более одного раза, что означает, что мне не нужно удалять его из списка списков после выбора.

Мне удалось создать список списков, где каждый вторичный список соответствуетРегион и его содержимое соответствуют случайным образом сгенерированным клиентским кодам. Но когда я использую функцию random.choice () для создания моего нового списка со случайными значениями, я получаю x количество случайных списков из доступных списков, а не случайные значения, выбранные из ВСЕХ списков.

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 ]

1 голос
/ 23 октября 2019

Вы не выбираете случайный элемент из этого вложенного списка, но завершаете вложенный список.

Сначала получите случайный вложенный список, а затем выберите элемент случайным образом

for i in range(10):
    rand_list = random.choice(codigo_cliente)
    thislist.append(random.choice(rand_list))
1 голос
/ 23 октября 2019

Используйте 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']
1 голос
/ 23 октября 2019

Weighted Choice

random.choices(population, weights, k) принимает список весов для вашего случайного выбора. Таким образом, вы можете указать длину подсписков в виде весов:

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

и позволить ему выбрать подсписок для вас (вы также можете указать 10 раз выбрать подсписок с помощью k=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)
]

Ссылка: Взвешенная версия 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)

Различные подходы к сглаживанию вложенных списков можно найти здесь: Как сделать плоский список из списка списков?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...