Python lambda使用for循环来动态添加参数

时间:2016-06-17 10:08:21

标签: python lambda

我有以下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>

答案可以是任何形式,前提是我可以获得所需的约束函数。

2 个答案:

答案 0 :(得分:4)

首先,不要在不需要它的地方使用lambda

PEP8

  

始终使用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个列表keysthresholdscmpfuncs应具有相同的长度,因为每个元素都构成规则三元组。

举个例子:

>>> 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