多键多值非确定性python字典
python中已经有一个函数,还有一个多值dict。我需要一个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']较低,但可能 单个输出值应根据键的规则概率确定(模糊) 例:在上述情况下,规则可能是
# 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)