我有以下lambda表达式:
constraints = lambda values: (
values['volume'] < 10,
values['mass'] < 100,
values['nItems'] <= 10,
values['nItems'] >= 5
)
我有一个包含品牌(动态填充)的列表,例如
brands = ['nestle', 'gatorate']
我希望能够动态添加其他表达式:
constraints = lambda values: (
values['volume'] < 10,
values['mass'] < 100,
values['nItems'] <= 10,
values['nItems'] >= 5,
#dynamically adds these parameters
values['nestle'] < 5,
values['gatorate'] < 5
)
如何使用 for 循环来迭代品牌并从品牌列表中动态填充其他参数到约束?< / p>
答案可以是任何形式,前提是我可以获得所需的约束函数。
答案 0 :(得分:4)
首先,不要在不需要它的地方使用lambda
始终使用def语句而不是赋值语句 将lambda表达式直接绑定到标识符。
是:
def f(x):返回2 * x
没有
f = lambda x:2 * x
第一种形式表示生成的函数对象的名称是 特别是&#39; f&#39;而不是通用的&#39;。这是更多 通常用于回溯和字符串表示。使用 赋值语句消除了lambda的唯一好处 表达式可以提供一个明确的def语句(即它可以 被嵌入一个更大的表达式中)
现在解决方案。列出将检查您的值的函数列表。
更新列表意味着更新约束。
def _constrain_main(values):
"""Static constraints"""
return (values['volume'] < 10 and values['mass'] < 100 and
values['nItems'] <= 10 and values['nItems'] >= 5)
def constrain(values):
"""Check for all constraints"""
return all(c(values) for c in constraints)
# list of constraints
constraints = [_constrain_main]
# example
values = {
'volume': 8,
'mass': 80,
'nItems': 8,
'nestle': 6,
'gatorate': 6,
}
print(constrain(values)) # True
# now append other lambdas (lambda is desired here)
constraints.append(lambda values: values['nestle'] < 5)
constraints.append(lambda values: values['gatorate'] < 5)
print(constrain(values)) # False
答案 1 :(得分:1)
您可以通过适当的功能替换lambda并获得一些加速。没有什么可以阻止你的lambda成为一个函数。
此外,您无法向函数添加动态表达式。最接近的方法是将键和阈值作为参数传递给您的函数:
def comparevalues(values, keys, thresholds, cmpfuncs):
return [f(values[k], t) for f, k, t in zip(cmpfuncs, keys, thresholds)]
此处values
是字典,keys
是每个&#34;规则&#34;中使用的密钥列表,threshold
是应用于每个&#34;的阈值。排除&#34; cmpfuncs
是每个规则中使用的比较函数(例如<
,<=
,>
...),如果它们很复杂,您可以创建自己的运算符您可以使用python's operators:
>>> import operator as op
>>> (5 > 6) == op.gt(5, 6) # Same operation, explicit vs function call
所有3个列表keys
,thresholds
和cmpfuncs
应具有相同的长度,因为每个元素都构成规则三元组。
举个例子:
>>> import operator as op
>>> dictionary = {'a': 5, 'b': 10}
>>> keys = ['a', 'b', 'a']
>>> thresholds = [1, 4, 5]
>>> cmpfuncs = [op.gt, op.gt, op.lt]
>>> comparevalues(dictionary, keys, thresholds, cmpfuncs)
[True, True, False]
以上是制定3条规则:(1)&#39; a&#39; &GT; 1,(2)&#39; b&#39; &GT; 4和(3)&#39; a&#39; &LT; 5.请注意op.gt = >
和op.lt = <
。
如果您想动态添加更多运算符,您只需维护keys
,threshodls and
cmpfuncs`的全局列表,用新规则更新它们,并在每次函数调用时传递它们。
既然已经解释了这种方法,那么找到一种方法来解决同样的问题 portable :
def comparerules(values, rules):
return [f(values[k], t) for f, k, t in rules]
方法与上述相同,但在这种情况下rules
是三元组列表,其中每个三元组都是(cmpfunc, key, threshold
形式的元组。
使用此功能与上述示例具有相同的规则:
>>> values = {'a': 5, 'b': 10}
>>> rules = [(op.gt, 'a', 1), (op.gt, 'b', 4), (op.lt, 'a', 5)]
>>> comparerules(values, rules)
[True, True, False]
这样,您只需要维护一个全局 rules
数组,编辑它以附加/删除新规则,并在每个函数调用中发送它:
>>> rules += [(op.gt, 'b', 10)] # values['b'] > 10
>>> comparerules(values, rules)
[True, True, False, False]
最后,要检查values
是否满足所有条件,只需使用python&#39; s all
:
>>> all(comparerules(values, rules))
False