首页 > 解决方案 > 从字典列表中选择随机样本,具有值条件

问题描述

我有一个这样的字典列表

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 个?例如,假设上面的列表很大,我想返回一个每个 prefix 有 5 个的 dicts 列表。所以我会得到一个包含 15 个字典、5 个带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 个字典。

标签: pythondictionary

解决方案


将前缀值作为键的字典分组,并使用默认字典作为值列出。然后提取每个元素的 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 & 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_'}]

推荐阅读