如何创建一个接受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.
"""
我该如何创建这种类型的功能?
感谢任何帮助。
答案 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
表示将值列表缩减为单个值。