Выбор случайной выборки из списка словарей с условием значения

#python #dictionary

#python #словарь

Вопрос:

У меня есть список словарей, подобных этому:

 list_of_dicts = [
    {'db': 'redshift', 'table': 'metrics', 'prefix': 'abc_'},
    {'db': 'blueshift', 'table': 'colors', 'prefix': 'abc_'},
    {'db': 'orangeshift', 'table': 'people', 'prefix': 'def_'},
    {'db': 'greenshift', 'table': 'money', 'prefix': 'def_'},
    {'db': 'purpleshift', 'table': 'props', 'prefix': 'ghi_'},
    {'db': 'brownshift', 'table': 'stages', 'prefix': 'ghi_'},
...
]
 

Как я могу извлечь N из каждого префикса? Например, представьте, что приведенный выше список был большим, и я хотел получить обратно список dicts, содержащий по 5 каждого префикса. Итак, я бы получил список из 15 dicts, 5 dicts с abc_ префиксом, 5 с def_ и 5 с ghi_

Ожидаемый результат будет:

 result = [
    {'db': 'redshift', 'table': 'metrics', 'prefix': 'abc_'},
    {'db': 'blueshift', 'table': 'colors', 'prefix': 'abc_'},
    {'db': 'orangeshift', 'table': 'people', 'prefix': 'abc_'},
    {'db': 'greenshift', 'table': 'money', 'prefix': 'abc_'},
    {'db': 'purpleshift', 'table': 'props', 'prefix': 'abc_'},
    {'db': 'redshift', 'table': 'metrics', 'prefix': 'def_'},
    {'db': 'blueshift', 'table': 'colors', 'prefix': 'def_'},
    {'db': 'orangeshift', 'table': 'people', 'prefix': 'def_'},
    {'db': 'greenshift', 'table': 'money', 'prefix': 'def_'},
    {'db': 'purpleshift', 'table': 'props', 'prefix': 'def_'},
    {'db': 'redshift', 'table': 'metrics', 'prefix': 'ghi_'},
    {'db': 'blueshift', 'table': 'colors', 'prefix': 'ghi_'},
    {'db': 'orangeshift', 'table': 'people', 'prefix': 'ghi_'},
    {'db': 'greenshift', 'table': 'money', 'prefix': 'ghi_'},
    {'db': 'purpleshift', 'table': 'props', 'prefix': 'ghi_'},
]
 

Итак, 5 dicts для каждого отдельного префикса были случайным образом извлечены из большого списка dicts.

Ответ №1:

сгруппируйте dicts со значением префикса в качестве ключа и перечислите как значение с defaultdict . Затем извлеките n элементов каждого (здесь я выбрал 2 случайных элемента из каждого списка), при необходимости «сгладьте» списки с помощью itertools.chain

 import collections,random, itertools

list_of_dicts = [
    {'db': 'redshift', 'table': 'metrics', 'prefix': 'abc_'},
    {'db': 'blueshift', 'table': 'colors', 'prefix': 'abc_'},
    {'db': 'orangeshift', 'table': 'people', 'prefix': 'def_'},
    {'db': 'greenshift', 'table': 'money', 'prefix': 'def_'},
    {'db': 'purpleshift', 'table': 'props', 'prefix': 'ghi_'},
    {'db': 'brownshift', 'table': 'stages', 'prefix': 'ghi_'}
]

d = collections.defaultdict(list)
# group the dicts by prefix
for lst in list_of_dicts:
    d[lst["prefix"]].append(lst)

# pick some dicts in each group amp; flatten the result
# a rare case where the keys aren't important in that step
result = list(itertools.chain.from_iterable(random.sample(v,2) for v in d.values()))


print(result)
 

один вывод:

 [{'db': 'redshift', 'table': 'metrics', 'prefix': 'abc_'},
  {'db': 'blueshift', 'table': 'colors', 'prefix': 'abc_'},
 {'db': 'greenshift', 'table': 'money', 'prefix': 'def_'},
  {'db': 'orangeshift', 'table': 'people', 'prefix': 'def_'}, 
{'db': 'brownshift', 'table': 'stages', 'prefix': 'ghi_'},
 {'db': 'purpleshift', 'table': 'props', 'prefix': 'ghi_'}]