There is already a multi key dict in python and also a multivalued dict. I needed a python dictionary which is both:
example:
# probabilistically fetch a
the single output value should be probabilistically determined (fuzzy) based on a rule from keys eg:in above case rule could be if keys have both "red" and "blue" then return "baloon" 80% of time if only blue then return "toy" 15% of time else "car" 5% of time.
Bare in mind your case analysis is not complete, and it's ambiguous, but you can do the following "in spirit" (fleshing out the desired results):
import random
def randomly_return(*colors):
colors = set(*colors)
if 'red' in colors and 'blue' in colors:
if random.random() < 0.8: # 80 % of the time
return "baloon"
if 'blue' in colors and len(colors) == 1: # only blue in colors
if random.random() < 0.15:
return "toy"
else:
if random.random() < 0.05:
return "car"
# other cases to consider
I would keep this as a function, because it is a function! But if you insist to make it dict-like, then python let's you do this by overriding __getitem__
(IMO it's not pythonic).
class RandomlyReturn(object):
def __getitem__(self, *colors):
return randomly_return(*colors)
>>> r = RandomlyReturn()
>>> r["red", "blue"] # 80% of the time it'll return "baloon"
"baloon"
From your clarification, OP wants to pass and generate:
randreturn((haseither(red,blue),baloon:0.8),((hasonly(blue),toy:0.15)),(default(),car:0.05)))
you want to generate a function as follows:
funcs = {"haseither": lambda needles, haystack: any(n in haystack for n in needles),
"hasonly": lambda needles, haystack: len(needles) == 1 and needles[1] in haystack}
def make_random_return(crits, default):
def random_return(*colors):
colors = set(*colors)
for c in crits:
if funcs[c["func"]](c["args"], colors) and random.random() > c["with_prob"]:
return c["return_value"]
return default
return random_return
where the crit and default in this case would be:
crit = [{"func": "haseither", "args": ("red", "blue"), "return_value": "baloon", "with_prob": 0.8}, ...]
default = "car" # ??
my_random_return = make_random_return(crits, default)
As I say, your probabilities are ambiguous/don't add up, so you're most likely going to need to tweak this...
You can extend the class definition by passing crit and default upon instantiation:
class RandomlyReturn(object):
def __init__(self, crit, default):
self.randomly_return = make_random_return(crit, default)
def __getitem__(self, *colors):
return self.randomly_return(*colors)
>>> r = RandomlyReturn(crit, default)
>>> r["red", "blue"] # 80% of the time it'll return "baloon"
"baloon"