Reputation: 1311
I have foreach function which calls specified function on every element which it contains. I want to get minimum from thise elements but I have no idea how to write lambda or function or even a class that would manage that. Thanks for every help.
o.foreach( lambda i: i.call() )
or
o.foreach( I.call )
I don't like to make a lists or other objects. I want to iterate trough it and find min.
I manage to write a class that do the think but there should be some better solution than that:
class Min:
def __init__(self,i):
self.i = i
def get_min(self):
return self.i
def set_val(self,o):
if o.val < self.i: self.i = o.val
m = Min( xmin )
self.foreach( m.set_val )
xmin = m.get_min()
Ok, so I suppose that my .foreach method is non-python idea. I should do my Class iterable because all your solutions are based on lists and then everything will become easier.
In C# there would be no problem with lambda function like that, so I though that python is also that powerful.
Upvotes: 6
Views: 23799
Reputation: 76725
Okay, one thing you need to understand: lambda
creates a function object for you. But so does plain, ordinary def
. Look at this example:
lst = range(10)
print filter(lambda x: x % 2 == 0, lst)
def is_even(x):
return x % 2 == 0
print filter(is_even, lst)
Both of these work. They produce the same identical result. lambda
makes an un-named function object; def
makes a named function object. filter()
doesn't care whether the function object has a name or not.
So, if your only problem with lambda
is that you can't use =
in a lambda
, you can just make a function using def
.
Now, that said, I don't suggest you use your .foreach()
method to find a minimum value. Instead, make your main object return a list of values, and simply call the Python min()
function.
lst = range(10)
print min(lst)
EDIT: I agree that the answer that was accepted is better. Rather than returning a list of values, it is better to define __iter__()
and make the object iterable.
Upvotes: 1
Reputation: 4377
Writing foreach
method is not very pythonic. You should better make it an iterator so that it works with standard python functions like min
.
Instead of writing something like this:
def foreach(self, f):
for d in self._data:
f(d)
write this:
def __iter__(self):
for d in self._data:
yield d
Now you can call min
as min(myobj)
.
Upvotes: 5
Reputation: 237080
You can't do this with foreach
and a lambda. If you want to do this in a functional style without actually using min
, you'll find reduce
is pretty close to the function you were trying to define.
l = [5,2,6,7,9,8]
reduce(lambda a,b: a if a < b else b, l[1:], l[0])
Upvotes: 7
Reputation: 96830
I have foreach function which calls specified function on every element which it contains
It sounds, from the comment you subsequently posted, that you have re-invented the built-in map
function.
It sounds like you're looking for something like this:
min(map(f, seq))
where f
is the function that you want to call on every item in the list.
As gnibbler shows, if you want to find the value x
in the sequence for which f(x)
returns the lowest value, you can use:
min(seq, key=f)
...unless you want to find all of the items in seq
for which f
returns the lowest value. For instance, if seq
is a list of dictionaries,
min(seq, key=len)
will return the first dictionary in the list with the smallest number of items, not all dictionaries that contain that number of items.
To get a list of all items in a sequence for which the function f
returns the smallest value, do this:
values = map(f, seq)
result = [seq[i] for (i, v) in enumerate(values) if v == min(values)]
Upvotes: 1
Reputation: 304355
Suppose you have
>>> seq = range(-4,4)
>>> def f(x):
... return x*x-2
for the minimum value of f
>>> min(f(x) for x in seq)
-2
for the value of x at the minimum
>>> min(seq, key=f)
0
of course you can use lambda too
>>> min((lambda x:x*x-2)(x) for x in range(-4,4))
-2
but that is a little ugly, map looks better here
>>> min(map(lambda x:x*x-2, seq))
-2
>>> min(seq,key=lambda x:x*x-2)
0
Upvotes: 0
Reputation: 3565
Python has built-in support for finding minimums:
>>> min([1, 2, 3])
1
If you need to process the list with a function first, you can do that with map:
>>> def double(x):
... return x * 2
...
>>> min(map(double, [1, 2, 3]))
2
Or you can get fancy with list comprehensions and generator expressions, for example:
>>> min(double(x) for x in [1, 2, 3])
2
Upvotes: 13