编辑:我已将其修改为您的新规范。
也许有点矫枉过正。但这有效。 (请原谅可怕的变量名)
这不是最有效的方法,但它遵循合乎逻辑的步骤(至少对我而言)希望这能满足您的需要,但您应该以此为指导并对其进行改进以满足您的特定需求。
from collections import defaultdict
from operator import itemgetter
from pprint import pprint
from re import match
## Class to help display the results as you want
class Organizer():
def __getitem__(self):
return Organizer()
def __init__(self):
self.normal = []
self.parens = []
self.brackets = []
self.fancy = []
def __str__(self):
ret = ''
for group, a, z in [(self.normal, '', ''),
(self.parens, '(', ')'),
(self.brackets, '[', ']'),
(self.fancy, '{', '}')]:
if group: # If there is something to format
ret += self._frmt(group, a, z)
return ret.strip(', ') # Remove extra formatting.
def _frmt(self, group, a, z):
return ', {}{}{}'.format(a, ', '.join(sorted(group)), z)
## Function that does what you want.
def match_to_wildcards(key_value_pairs):
values_as_keys, partial = defaultdict(Organizer), {}
# Prepare the initial groups.
for key, value in key_value_pairs.items():
if '-' in value:
partial[key] = value
else:
values_as_keys[value].normal.append(key)
# Clean up the partial matches.
partial_matches = {k: [f for f in values_as_keys if match(v.replace('-', '.'), f)] for k, v in partial.items()}
for key, values in partial_matches.items():
if not values:
continue
for value in values:
if len(values) > 1:
values_as_keys[value].brackets.append(key)
else:
values_as_keys[value].parens.append(key)
if key in partial:
partial.pop(key)
# Filter the last unmatched items.
combined_unmatched = {u: [v for v in partial.values() if match(u.replace('-', '.'), v)] for u in partial.values()}
need_to_be_rearranged = {k: [(p, p.count('-')) for p, j in combined_unmatched.items() if k in j] for k, v in combined_unmatched.items() if len(v) == 1}
# Sort the last unmatched items.
for key, value in partial.items():
if value in need_to_be_rearranged:
value_key = max(need_to_be_rearranged[value], key=itemgetter(1))[0]
values_as_keys[value_key].fancy.append(key)
else:
values_as_keys[value].fancy.append(key)
# Return the results, format them.
return {str(v): k for k, v in values_as_keys.items()}
现在使用您的数据运行代码。
## Test
data_set = {
'k1': 'AAB',
'k2': 'AAB',
'k3': 'ABA',
'k4': 'AAB',
'k5': 'A--',
'k6': 'AB-',
'k7': 'BB-',
'k8': 'B--',
'k9': 'B-B',
'k10': '--C'
}
pprint(match_to_wildcards(data_set))
# {'k1, k2, k4, [k5]': 'AAB',
# 'k3, (k6), [k5]': 'ABA',
# '{k10}': '--C',
# '{k7, k8, k9}': 'B--'}