Multikey Multivalue Non Deterministic python dictionary

前端 未结 4 1999
清酒与你
清酒与你 2021-02-05 23:08

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         


        
4条回答
  •  一生所求
    2021-02-05 23:23

    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"
    

提交回复
热议问题