多键多值非确定性python字典

多键多值非确定性python字典,python,dictionary,data-structures,recommendation-engine,fuzzy-logic,Python,Dictionary,Data Structures,Recommendation Engine,Fuzzy Logic,python中已经有一个函数,还有一个多值dict。我需要一个python字典,它是: 例如: # probabilistically fetch any one of baloon, toy or car d['red','blue','green']== "baloon" or "car" or "toy" d['red']==d['green']的概率很高,d['red']的概率很高=d['red']较低,但可能 单个输出值应根据键的规则概率确定(模糊) 例:在上述情况下,规则可能是

python中已经有一个函数,还有一个多值dict。我需要一个python字典,它是:

例如:

# probabilistically fetch any one of baloon, toy or car
d['red','blue','green']== "baloon" or "car" or "toy"  
d['red']==d['green']的概率很高,d['red']的概率很高=d['red']较低,但可能

单个输出值应根据键的规则概率确定(模糊) 例:在上述情况下,规则可能是,如果钥匙同时有“红色”和“蓝色”,则80%的时间返回“巴伦”,如果只有蓝色,则15%的时间返回“玩具”,否则5%的时间返回“汽车”

setitem方法的设计应确保以下内容是可能的:

d["red", "blue"] =[
    ("baloon",haseither('red','green'),0.8),
    ("toy",.....)
    ,....
]
上面使用谓词函数和相应的概率为字典分配多个值。与上面的作业列表相比,最好使用字典作为作业:

d["red", "blue"] ={ 
    "baloon": haseither('red','green',0.8),
    "toy": hasonly("blue",0.15),
    "car": default(0.05)
}
在上述情况下,如果出现“红色”或绿色,阳台将在80%的时间内返回 ,如果蓝色出现,则按15%的时间归还玩具,无条件按5%的时间归还汽车

在python中是否有任何现有的数据结构已经满足上述要求?如果否,那么如何修改multikeydict代码以满足python中的上述要求

如果使用dictionary,则可以有一个配置文件或使用适当的嵌套decorator来配置上述概率谓词逻辑,而无需硬编码if\else语句


注意:以上是基于规则的自动响应程序应用程序的有用自动机,因此请务必告诉我python中是否有类似的基于规则的框架可用,即使它不使用字典结构?

如果可以更改数据结构,则使用返回所需数据的函数会更简单。这将是完全灵活的,可以容纳任何类型的数据,如果您以后需要更改它们

import random

def myfunc(*args):
    if 'red' in args:
        return 'blue'
    elif 'green' in args or 'violet' in args:
        return 'violet'
    else:
        r = random.random()
        if 0 < r < 0.2:
            return 'blue'
        else:
            return 'green'

print(myfunc('green', 'blue'))
print(myfunc('yellow'))
单个输出值应根据按键的规则进行概率确定(模糊),例如:在上述情况下,如果按键同时具有“红色”和“蓝色”,则规则可能是80%的时间返回“baloon”,如果只有蓝色,则返回“toy”15%的时间,否则返回“car”5%的时间

请记住,您的案例分析并不完整,而且模棱两可,但您可以“在精神上”执行以下操作(充实所需的结果):


根据您的说明,OP希望通过并生成:

randreturn((HasOrit(红色,蓝色),baloon:0.8),((hasonly(蓝色),toy:0.15)),(默认值(‌​),汽车:0.05))

您希望生成一个函数,如下所示:

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
在这种情况下,临界值和默认值为:

crit = [{"func": "haseither", "args": ("red", "blue"), "return_value": "baloon", "with_prob": 0.8}, ...]
default = "car"  # ??
my_random_return = make_random_return(crits, default)
正如我所说,你的概率是模糊的/不加起来,所以你很可能需要调整这个

您可以通过在实例化时传递crit和default来扩展类定义:

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"
模拟多键词典 不允许同时使用多个键

(例如,
d[“红色”、“绿色”]

可以使用或键模拟多键。如果顺序不重要,看起来是最好的(实际上是可散列的,因此[
“red”,“blue”]
是相同的a
[“blue”,“red”]

模拟多值字典 通过使用某些数据类型,多值是固有的,可以方便地编制索引。标准应提供这一点

非决定论 使用规则和假设1定义的概率分布,使用python文档中的

multikeymultipalnondeterministicdict
Class 多好的名字啊。\o/-好极了

此类接受多个键,这些键定义了一个由多个值组成的概率规则集。在项目创建()期间,将为所有键1的组合预计算所有值概率。在项目访问()期间,将选择预计算的概率分布,并基于随机加权选择对结果进行评估

定义 用法 测试 检查概率

N = 10000
red_green_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}
red_blue_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}
blue_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}
red_blue_green_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}
default_test = {'car':0.0, 'toy':0.0, 'ballon':0.0}

for _ in xrange(N):
    red_green_test[d["red","green"]] += 1.0
    red_blue_test[d["red","blue"]] += 1.0
    blue_test[d["blue"]] += 1.0
    default_test[d["green"]] += 1.0
    red_blue_green_test[d["red","blue","green"]] += 1.0

print 'red,green test      =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in red_green_test.items())
print 'red,blue test       =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in red_blue_test.items())
print 'blue test           =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in blue_test.items())
print 'default test        =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in default_test.items())
print 'red,blue,green test =', ' '.join('{0}: {1:05.2f}%'.format(key, 100.0*val/N) for key, val in red_blue_green_test.items())

概率匹配规则!
脚注
  • 分布假设

    由于规则集未完全定义,因此对概率分布进行了假设,大部分假设在
    multi_val_rule_prob()中完成
    。基本上,任何未定义的概率都将均匀分布在剩余的值上。这对所有键组合都是如此,并为随机加权选择创建一个通用键接口

    给出了示例规则集

    d["red","blue","green"] = {
        # {rule_set} : {result: probability}
        frozenset(["red", "green"]): {"ballon": 0.8},
        frozenset(["blue"]): {"toy": 0.15},
        frozenset([]): {"car": 0.05}
    }
    
    这将创建以下发行版

    'red'           = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    'green'         = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    'blue'          = [('car', 0.425), ('toy', 0.150), ('ballon', 0.425)]
    'blue,red'      = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    'green,red'     = [('car', 0.098), ('toy', 0.098), ('ballon', 0.800)]
    'blue,green'    = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    'blue,green,red'= [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
     default        = [('car', 0.050), ('toy', 0.475), ('ballon', 0.475)]
    
    如果这是不正确的,请告知


  • OP的目标如下:

    d["red", "blue"] ={ 
        "baloon": haseither('red','green',0.8),
        "toy": hasonly("blue",0.15),
        "car": default(0.05)
    }  
    
    但这是带有嵌入式逻辑的数据。为每个值定义一个函数非常繁琐。我建议将数据和逻辑分离

    Python对此有一种数据类型,即
    class
    。可以将
    class
    的可调用实例分配给
    dict
    ,让
    dict
    传递键并调用对象以返回结果

    我继承并扩展了
    multiple\u key\u dict
    ,以支持多键提取,并将键传递给对象并调用存储在dict中的对象

    我假设数据是按照规则重新计算的。这是
    rule
    类,它有一个规则列表。一个规则是Python表达式,它可以访问
    len
    函数和
    keys
    列表。因此,可以编写一个规则,如
    len(keys)==1和键中的“blue”

    class Rule(object):
    
        def __init__(self, rule, data):
            self.rule = rule
            self.data = data
    
    这是一个既有数据集又有规则的
    Data

    class Data(object):
        def __init__(self, rules):
            self.rules= rules
    
        def make_choice(self, data):
            data = tuple(self.make_list_of_values(data))
            return random.choice(data)
    
        def make_list_of_values(self, data):
            for val, weight in data:
                percent = int(weight * 100)
                for v in [val] * percent:
                    yield v
    
        def __call__(self, keys):
            for rule in self.rules:
                if eval(rule.rule,dict(keys=keys)):
                    return self.make_choice(rule.data)
    
    这是
    RuleDict
    ,但无法提取非可调用项

    class RuleDict(multi_key_dict):
        def __init__(self, *args, **kwargs):
            multi_key_dict.__init__(self, *args, **kwargs)
    
        def __getitem__(self, keys):
            if isinstance(keys, str):
                keys = (keys, )
            keys_set = frozenset(keys)
            for key in self.keys():
                key = frozenset(key)
                if keys_set <= key:
                    return multi_key_dict.__getitem__(self,keys[0])(keys)
            raise KeyError(keys)
    
    d['red','green']
    调用已分配的带有键的对象并返回结果

    另一种方法是,使dict可调用。这似乎是一种合理的方法,因为数据和逻辑是分开的。通过这种方法,您将键和逻辑(可调用)传递给dict并返回结果。f.e

    def f(keys, data):
        pass # do the logic and return data
    
    d['red','blue','green'] = ('baloon', 'car', 'toy')
    
    现在调用
    dict

    d(('red','blue'),f)
    
    这是可调用的
    dict
    d["red", "blue"] ={ 
        "baloon": haseither('red','green',0.8),
        "toy": hasonly("blue",0.15),
        "car": default(0.05)
    }  
    
    class Rule(object):
    
        def __init__(self, rule, data):
            self.rule = rule
            self.data = data
    
    class Data(object):
        def __init__(self, rules):
            self.rules= rules
    
        def make_choice(self, data):
            data = tuple(self.make_list_of_values(data))
            return random.choice(data)
    
        def make_list_of_values(self, data):
            for val, weight in data:
                percent = int(weight * 100)
                for v in [val] * percent:
                    yield v
    
        def __call__(self, keys):
            for rule in self.rules:
                if eval(rule.rule,dict(keys=keys)):
                    return self.make_choice(rule.data)
    
    class RuleDict(multi_key_dict):
        def __init__(self, *args, **kwargs):
            multi_key_dict.__init__(self, *args, **kwargs)
    
        def __getitem__(self, keys):
            if isinstance(keys, str):
                keys = (keys, )
            keys_set = frozenset(keys)
            for key in self.keys():
                key = frozenset(key)
                if keys_set <= key:
                    return multi_key_dict.__getitem__(self,keys[0])(keys)
            raise KeyError(keys)
    
    d = RuleDict()
    rule1 = Rule('"red" in keys and "green" in keys',(('baloon',0.8), ('car',0.05), ('toy',0.15)))
    rule2 = Rule('len(keys) ==1 and "blue" in keys',(('baloon',0.25), ('car',0.35), ('toy',0.15)))
    data = Data((rule1, rule2))
    d['red','blue','green'] = data
    
    print(d['red','green'])  
    
    def f(keys, data):
        pass # do the logic and return data
    
    d['red','blue','green'] = ('baloon', 'car', 'toy')
    
    d(('red','blue'),f)
    
    class callable_mkd(multi_key_dict):
        def __init__(self, *args, **kwargs):
            multi_key_dict.__init__(self, *args, **kwargs)
    
        def __call__(self, keys, process=None):
            keys_set = frozenset(keys)
            for key in self.keys():
                key = frozenset(key)
                if keys_set <= key:
                    if process:
                        return process(keys, self[keys[0]])
                    return self[keys[0]]
            raise KeyError(keys)