How do I create a function which accepts lambda expression like,
# 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.
"""
how do i create that type of function?
Any help that is appreciated.
A lambda can be treated like any regular variable that is callable:
def function(data, f):
return f(data)
In your case to create a max function:
def max(data, key = lambda x: x):
m = lambda a,b: a if key(a) > key(b) else b
return reduce(m, data)
or more verbose:
def max(data, key = lambda x: x):
max_ = data[0]
for d in data:
if key(d) > key(max_): max_ = d
return max_
How to optimize this to avoid calling key
too often is left as an exercise for the reader.
More Examples
Max:
>>> reduce(lambda a,b: a if a['hi'] > b['hi'] else b, [{"hi":0},{"hi":-1},{"hi":9}])
{'hi': 9}
Sum:
>>> reduce(lambda a,b: {"hi":a["hi"]+b["hi"]}, [{"hi":1},{"hi":2},{"hi":3}])
{'hi': 6}
More generic:
>>> 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}
It depends on what you actually want to do. If you want a reduction that applies a bin op use generic
if you want a reduction that decides between taking a,b use generic_select
.
Reduce
Reduce isn't available in python3 without an import but you can import it from the functools package. It's a very common and simple pattern:
>>> 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
Sometimes it may be necessary to specify an initial value instead of using 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]
A reduction of lambda a,b: [b]+a
reverses a list. reduce
means to reduce a list of values to a single value.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.