I have a list of dictionaries:-
test = [{'Sequence': 'A', 'Tag': '20', 'Option': None},
{'Sequence': 'A', 'Tag': '23', 'Option': None},
{'Sequence': 'A', 'Tag': '51A', 'Option': None},
{'Sequence': 'A', 'Tag': '50A', 'Option': 'A'},
{'Sequence': 'A', 'Tag': '50A', 'Option': 'F'},
{'Sequence': 'A', 'Tag': '50A', 'Option': 'K'},
{'Sequence': 'A', 'Tag': '52A', 'Option': 'A'},
{'Sequence': 'A', 'Tag': '52A', 'Option': 'B'},
{'Sequence': 'A', 'Tag': '52A', 'Option': 'C'},
{'Sequence': 'A', 'Tag': '26T', 'Option': None},
{'Sequence': 'A', 'Tag': '77B', 'Option': None},
{'Sequence': 'A', 'Tag': '71A', 'Option': None},
{'Sequence': 'B', 'Tag': '36', 'Option': None},
{'Sequence': 'B', 'Tag': '21', 'Option': None},
{'Sequence': 'B', 'Tag': '32B', 'Option': None},
{'Sequence': 'B', 'Tag': '32B', 'Option': None},
{'Sequence': 'B', 'Tag': '50A', 'Option': 'A'},
{'Sequence': 'B', 'Tag': '50A', 'Option': 'F'},
{'Sequence': 'B', 'Tag': '50A', 'Option': 'K'},
{'Sequence': 'B', 'Tag': '52A', 'Option': 'A'},
{'Sequence': 'B', 'Tag': '52A', 'Option': 'B'},
{'Sequence': 'B', 'Tag': '52A', 'Option': 'C'},
{'Sequence': 'B', 'Tag': '57A', 'Option': 'A'},
{'Sequence': 'B', 'Tag': '57A', 'Option': 'C'},
{'Sequence': 'B', 'Tag': '59A', 'Option': None},
{'Sequence': 'B', 'Tag': '59A', 'Option': 'A'},
{'Sequence': 'B', 'Tag': '59A', 'Option': 'F'},
{'Sequence': 'B', 'Tag': '70', 'Option': None},
{'Sequence': 'B', 'Tag': '26T', 'Option': None},
{'Sequence': 'B', 'Tag': '77B', 'Option': None},
{'Sequence': 'B', 'Tag': '33B', 'Option': None},
{'Sequence': 'B', 'Tag': '33B', 'Option': None},
{'Sequence': 'B', 'Tag': '71A', 'Option': None},
{'Sequence': 'B', 'Tag': '71F', 'Option': None},
{'Sequence': 'B', 'Tag': '71F', 'Option': None},
{'Sequence': 'B', 'Tag': '71G', 'Option': None},
{'Sequence': 'B', 'Tag': '71G', 'Option': None},
{'Sequence': 'B', 'Tag': '36', 'Option': None},
{'Sequence': 'C', 'Tag': '32A', 'Option': None},
{'Sequence': 'C', 'Tag': '32A', 'Option': None},
{'Sequence': 'C', 'Tag': '32A', 'Option': None},
{'Sequence': 'C', 'Tag': '19', 'Option': None},
{'Sequence': 'C', 'Tag': '71G', 'Option': None},
{'Sequence': 'C', 'Tag': '71G', 'Option': None},
{'Sequence': 'C', 'Tag': '13C', 'Option': None},
{'Sequence': 'C', 'Tag': '53A', 'Option': 'A'},
{'Sequence': 'C', 'Tag': '53A', 'Option': 'C'},
{'Sequence': 'C', 'Tag': '54A', 'Option': None},
{'Sequence': 'C', 'Tag': '72', 'Option': None}]
and I am able to create a separate list of dictionaries based on "Sequence" key:
sorted_data = sorted(test, key=itemgetter('Sequence'))
for key, group in itertools.groupby(sorted_data, key=lambda x: x['Sequence']):
print(key, list(group))
A [{'Sequence': 'A', 'Tag': '20', 'Option': None}, {'Sequence': 'A', 'Tag': '23', 'Option': None}, {'Sequence': 'A', 'Tag': '51A', 'Option': None}, {'Sequence': 'A', 'Tag': '50A', 'Option': 'A'}, {'Sequence': 'A', 'Tag': '50A', 'Option': 'F'}, {'Sequence': 'A', 'Tag': '50A', 'Option': 'K'}, {'Sequence': 'A', 'Tag': '52A', 'Option': 'A'}, {'Sequence': 'A', 'Tag': '52A', 'Option': 'B'}, {'Sequence': 'A', 'Tag': '52A', 'Option': 'C'}, {'Sequence': 'A', 'Tag': '26T', 'Option': None}, {'Sequence': 'A', 'Tag': '77B', 'Option': None}, {'Sequence': 'A', 'Tag': '71A', 'Option': None}]
B [{'Sequence': 'B', 'Tag': '36', 'Option': None}, {'Sequence': 'B', 'Tag': '21', 'Option': None}, {'Sequence': 'B', 'Tag': '32B', 'Option': None}, {'Sequence': 'B', 'Tag': '32B', 'Option': None}, {'Sequence': 'B', 'Tag': '50A', 'Option': 'A'}, {'Sequence': 'B', 'Tag': '50A', 'Option': 'F'}, {'Sequence': 'B', 'Tag': '50A', 'Option': 'K'}, {'Sequence': 'B', 'Tag': '52A', 'Option': 'A'}, {'Sequence': 'B', 'Tag': '52A', 'Option': 'B'}, {'Sequence': 'B', 'Tag': '52A', 'Option': 'C'}, {'Sequence': 'B', 'Tag': '57A', 'Option': 'A'}, {'Sequence': 'B', 'Tag': '57A', 'Option': 'C'}, {'Sequence': 'B', 'Tag': '59A', 'Option': None}, {'Sequence': 'B', 'Tag': '59A', 'Option': 'A'}, {'Sequence': 'B', 'Tag': '59A', 'Option': 'F'}, {'Sequence': 'B', 'Tag': '70', 'Option': None}, {'Sequence': 'B', 'Tag': '26T', 'Option': None}, {'Sequence': 'B', 'Tag': '77B', 'Option': None}, {'Sequence': 'B', 'Tag': '33B', 'Option': None}, {'Sequence': 'B', 'Tag': '33B', 'Option': None}, {'Sequence': 'B', 'Tag': '71A', 'Option': None}, {'Sequence': 'B', 'Tag': '71F', 'Option': None}, {'Sequence': 'B', 'Tag': '71F', 'Option': None}, {'Sequence': 'B', 'Tag': '71G', 'Option': None}, {'Sequence': 'B', 'Tag': '71G', 'Option': None}, {'Sequence': 'B', 'Tag': '36', 'Option': None}]
C [{'Sequence': 'C', 'Tag': '32A', 'Option': None}, {'Sequence': 'C', 'Tag': '32A', 'Option': None}, {'Sequence': 'C', 'Tag': '32A', 'Option': None}, {'Sequence': 'C', 'Tag': '19', 'Option': None}, {'Sequence': 'C', 'Tag': '71G', 'Option': None}, {'Sequence': 'C', 'Tag': '71G', 'Option': None}, {'Sequence': 'C', 'Tag': '13C', 'Option': None}, {'Sequence': 'C', 'Tag': '53A', 'Option': 'A'}, {'Sequence': 'C', 'Tag': '53A', 'Option': 'C'}, {'Sequence': 'C', 'Tag': '54A', 'Option': None}, {'Sequence': 'C', 'Tag': '72', 'Option': None}]
However, while creating the sublists above if there is a duplicate tag present with different options for example tag '52A' in these cases:
{'Sequence': 'A', 'Tag': '52A', 'Option': 'A'},
{'Sequence': 'A', 'Tag': '52A', 'Option': 'B'},
{'Sequence': 'A', 'Tag': '52A', 'Option': 'C'}
I want to randomly select only 1 dictionary and update that dictionary-like below:-
{'Sequence': 'A', 'Tag': '52B', 'Option': 'B'}
Hope I am able to explain the problem. Any help is appreciated or if I need to rethink my approach of breaking down my original list.
CodePudding user response:
One way using random.choice
with collections.defaultdict
:
from itertools import groupby
from random import choice
from collections import defaultdict
res = defaultdict(list)
for (seq, tag), g in groupby(test, key=lambda x: (x["Sequence"], x["Tag"])):
res[seq].append(choice(list(g)))
Output:
defaultdict(list,
{'A': [{'Sequence': 'A', 'Tag': '20', 'Option': None},
{'Sequence': 'A', 'Tag': '23', 'Option': None},
{'Sequence': 'A', 'Tag': '51A', 'Option': None},
{'Sequence': 'A', 'Tag': '50A', 'Option': 'F'},
{'Sequence': 'A', 'Tag': '52A', 'Option': 'B'},
{'Sequence': 'A', 'Tag': '26T', 'Option': None},
{'Sequence': 'A', 'Tag': '77B', 'Option': None},
{'Sequence': 'A', 'Tag': '71A', 'Option': None}],
'B': [{'Sequence': 'B', 'Tag': '36', 'Option': None},
{'Sequence': 'B', 'Tag': '21', 'Option': None},
{'Sequence': 'B', 'Tag': '32B', 'Option': None},
{'Sequence': 'B', 'Tag': '50A', 'Option': 'A'},
{'Sequence': 'B', 'Tag': '52A', 'Option': 'C'},
{'Sequence': 'B', 'Tag': '57A', 'Option': 'C'},
{'Sequence': 'B', 'Tag': '59A', 'Option': 'A'},
{'Sequence': 'B', 'Tag': '70', 'Option': None},
{'Sequence': 'B', 'Tag': '26T', 'Option': None},
{'Sequence': 'B', 'Tag': '77B', 'Option': None},
{'Sequence': 'B', 'Tag': '33B', 'Option': None},
{'Sequence': 'B', 'Tag': '71A', 'Option': None},
{'Sequence': 'B', 'Tag': '71F', 'Option': None},
{'Sequence': 'B', 'Tag': '71G', 'Option': None},
{'Sequence': 'B', 'Tag': '36', 'Option': None}],
'C': [{'Sequence': 'C', 'Tag': '32A', 'Option': None},
{'Sequence': 'C', 'Tag': '19', 'Option': None},
{'Sequence': 'C', 'Tag': '71G', 'Option': None},
{'Sequence': 'C', 'Tag': '13C', 'Option': None},
{'Sequence': 'C', 'Tag': '53A', 'Option': 'C'},
{'Sequence': 'C', 'Tag': '54A', 'Option': None},
{'Sequence': 'C', 'Tag': '72', 'Option': None}]})
Insight:
choice(list(g))
will always return single item, so if there's duplicated tags, it does the random selection, and otherwise, return as it is (since no duplicate means single item).
CodePudding user response:
You can groupby
on Sequence
and Tag
, and using random.choice
select one item from each group. Then rearrange the dictionary again to drop Tag
from each key and create a dictionary of Sequence
keys.
from operator import itemgetter
from itertools import groupby
from random import choice
sorted_data = sorted(test, key=itemgetter('Sequence','Tag'))
out = {}
for key, group in groupby(sorted_data, key=itemgetter('Sequence','Tag')):
out.setdefault(key[0],[]).append(choice(list(group)))
Sample output:
{'A': [{'Sequence': 'A', 'Tag': '20', 'Option': None},
{'Sequence': 'A', 'Tag': '23', 'Option': None},
{'Sequence': 'A', 'Tag': '51A', 'Option': None},
{'Sequence': 'A', 'Tag': '50A', 'Option': 'A'},
{'Sequence': 'A', 'Tag': '52A', 'Option': 'A'},
{'Sequence': 'A', 'Tag': '26T', 'Option': None},
{'Sequence': 'A', 'Tag': '77B', 'Option': None},
{'Sequence': 'A', 'Tag': '71A', 'Option': None}],
'B': [{'Sequence': 'B', 'Tag': '36', 'Option': None},
{'Sequence': 'B', 'Tag': '21', 'Option': None},
{'Sequence': 'B', 'Tag': '32B', 'Option': None},
{'Sequence': 'B', 'Tag': '50A', 'Option': 'K'},
{'Sequence': 'B', 'Tag': '52A', 'Option': 'C'},
{'Sequence': 'B', 'Tag': '57A', 'Option': 'C'},
{'Sequence': 'B', 'Tag': '59A', 'Option': 'A'},
{'Sequence': 'B', 'Tag': '70', 'Option': None},
{'Sequence': 'B', 'Tag': '26T', 'Option': None},
{'Sequence': 'B', 'Tag': '77B', 'Option': None},
{'Sequence': 'B', 'Tag': '33B', 'Option': None},
{'Sequence': 'B', 'Tag': '71A', 'Option': None},
{'Sequence': 'B', 'Tag': '71F', 'Option': None},
{'Sequence': 'B', 'Tag': '71G', 'Option': None}],
'C': [{'Sequence': 'C', 'Tag': '32A', 'Option': None},
{'Sequence': 'C', 'Tag': '19', 'Option': None},
{'Sequence': 'C', 'Tag': '71G', 'Option': None},
{'Sequence': 'C', 'Tag': '13C', 'Option': None},
{'Sequence': 'C', 'Tag': '53A', 'Option': 'A'},
{'Sequence': 'C', 'Tag': '54A', 'Option': None},
{'Sequence': 'C', 'Tag': '72', 'Option': None}]}