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 any one of baloon, toy or car
d['red','blue','green']== "baloon" or "car" or "toy"
Probability of d['red']==d['green'] is high and Probability of d['red']!=d['red'] is low but possible
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.
The setitem method should be designed such that following is possible:
d["red", "blue"] =[
("baloon",haseither('red','green'),0.8),
("toy",.....)
,....
]
Above assigns multiple values to the dictionary with a predicate function and corresponding probability. And instead of the assignment list above even a dictionary as assignment would be preferable:
d["red", "blue"] ={
"baloon": haseither('red','green',0.8),
"toy": hasonly("blue",0.15),
"car": default(0.05)
}
In the above baloon will be returned 80% of time if "red" or green is present , return toy 15% of time if blue present and return car 5% of time without any condition.
Are there any existing data structures which already satisfy the above requirements in python? if no then how can multikeydict code be modified to meet the above requirements in python?
if using dictionary then there can be a configuration file or use of appropriate nested decorators which configures the above probabilistic predicate logics without having to hard code if \else statements .
Note: Above is a useful automata for a rule based auto responder application hence do let me know if any similar rule based framework is available in python even if it does not use the dictionary structure?
Simulated MultiKey Dictionary
multi_key_dict
did not allow__getitem__()
with multiple keys at onces...(e.g.
d["red", "green"]
)A multi key can be simulated with
tuple
orset
keys. If order does not matter,set
seems the best (actually the hashablefrozen set
, so that ["red", "blue"]
is the same a["blue", "red"]
.Simulated MultiVal Dictionary
Multi values are inherent by using certain datatypes, it can be any storage element that may be conveniently indexed. A standard
dict
should provide that.Non-determinism
Using a probability distribution defined by the rules and assumptions1, non-deterministic selection is performed using this recipe from the python docs.
MultiKeyMultiValNonDeterministicDict
ClassWhat a name. \o/-nice!
This class takes multiple keys that define a probabilistic rule set of multiple values. During item creation (
__setitem__()
) all value probabilities are precomputed for all combinations of keys1. During item access (__getitem__()
) the precomputed probability distribution is selected and the result is evaluated based on a random weighted selection.Definition
Usage
Testing
Check the probabilities
Probabilities match rules!
Footnotes
Distribution Assumption
Since the rule set is not fully defined, assumptions are made about the probability distributions, most of this is done in
multi_val_rule_prob()
. Basically any undefined probability will be spread uniformly over the remaining values. This is done for all combinations of keys, and creates a generalized key interface for the random weighted selection.Given the example rule set
this will create the following distributions
If this is incorrect, please advise.
If it is possible to change the data structure, it would be simpler to have a function returning the data you need. This will be completely flexible and could accommodate any kind of data, should you need to change them later.
output (the second line obviously changes):
The OP wants as follows,
but this is data with embeded logic. It's very tedious to define a function for every value. What I suggest is to seprate the data and logic.
Python has a data type for this, that's
class
. A callable instance of aclass
can be assigned to thedict
and let thedict
pass the keys and call the object to return the result.I've inherited and extended
multiple_key_dict
to support multi-key fetch and to pass keys to the object and call the object which has been stored in the dict.I assume data is recalculated per rule. This is
Rule
class, it has list of rules. A rule is a Python expressions and it has access tolen
function andkeys
list. So one can write a rule likelen(keys) == 1 and 'blue' in keys
.This is
Data
class which has both set of data and rules.This is
RuleDict
, but non-callables can not be fetched.usage example,
d['red','green']
calls the object, with keys, that was assigned and return the result.Another approach is, to make the
dict
callable. This one seems a sound approach, because data and logic are separate. By this, you pass the keys and the logic, a callable, to the dict and return the result. f.e.,Now call the
dict
This is callable
dict
. If no callable is given, just returns the whole data.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):
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).From your clarification, OP wants to pass and generate:
you want to generate a function as follows:
where the crit and default in this case would be:
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: