如何在python中创建接受lambda表达式的函数?

时间:2018-02-06 09:46:25

标签: python lambda

如何创建一个接受lambda表达式的函数,如

# dummy data
data = [{"dim":["abc","sdc"], "mea":[23,23,134]},{"dim":["jgdf","dfc"], "mea":[34,245,2345]}....]

"""
also note that data may be change, [{"x":[{"dim":["abc","sdc"], "mea":[23,23,134]},{"dim":["jgdf","dfc"], "mea":[34,245,2345]}....], "y":.....},...]

but data structure (dictionary) for keys "dim" & "mea" will remain same.
"""  

def function(data,key=lambda x: x):
    """
    Logic:

    sum1 = sum(i["mea"][0] for i in data)

    return [[data[i]["dim"],data[i]["mea"][0]] for i in range(len(data)) if data[i]["mea"][0] * len(data) / sum1 > 1]

    now i want equivalent lambda function that works for any data 
    constraint is that structure before "dim" & "mea" will change.
    """

我该如何创建这种类型的功能?

感谢任何帮助。

1 个答案:

答案 0 :(得分:0)

lambda可以像任何可调用的常规变量一样对待:

def function(data, f):
   return f(data)

在您创建最大功能的情况下:

def max(data, key = lambda x: x):
  m = lambda a,b: a if key(a) > key(b) else b
  return reduce(m, data)

或更详细:

def max(data, key = lambda x: x):
  max_ = data[0]
  for d in data:
    if key(d) > key(max_): max_ = d
  return max_

如何优化此操作以避免过于频繁地调用key,这仍然是读者的练习。

更多示例

最大:

>>> reduce(lambda a,b: a if a['hi'] > b['hi'] else b, [{"hi":0},{"hi":-1},{"hi":9}])
{'hi': 9}

和:

>>> reduce(lambda a,b: {"hi":a["hi"]+b["hi"]}, [{"hi":1},{"hi":2},{"hi":3}])
{'hi': 6}

更通用:

>>> def generic(data, f, key = lambda x: x, cons = lambda x: x):
...    return reduce(lambda a,b: cons(f(key(a),key(b))), data)
... 
>>> generic([{"hi":1},{"hi":2},{"hi":3}], lambda a,b: a*b, key = lambda x: x["hi"], cons = lambda x: {"hi":x})
{'hi': 6}

>>> def generic_select(data, f, key = lambda x: x):
...   return reduce(lambda a,b: a if f(key(a), key(b)) else b, data)
... 
>>> generic_select([{"hi":1,"a":"b"},{"hi":0,"a":"c"}], lambda a,b: True if a < b else False, key = lambda x: x["hi"])
{'a': 'c', 'hi': 0}

这取决于你真正想做的事情。如果您希望减少使用bin操作generic,如果您希望减少决定在a,b之间使用generic_select

<强>减少

如果没有导入,python3中没有Reduce,但您可以从functools包中导入它。这是一个非常普遍和简单的模式:

>>> def reduce_(data, f):
...   r = data[0]
...   for r_ in data[1:]:
...     r = f(r, r_)
...   return r
... 
>>> reduce_([1,2,3], lambda a,b: a+b)
6
>>> reduce_([1,2,3], lambda a,b: a if a > b else b)
3

有时可能需要指定初始值而不是使用data[0]

>>> def reduce1(data, init, f):
...   r = init
...   for r_ in data:
...     r = f(r, r_)
...   return r
... 
>>> reduce1([1,2,3], [], lambda a,b: [b]+a)
[3, 2, 1]

减少lambda a,b: [b]+a会使列表反转。 reduce表示将值列表缩减为单个值。