2009-10-27 131 views
5

我有foreach函数调用它包含的每个元素的指定函数。我想从这个元素中获得最小值,但是我不知道如何编写lambda或函数,甚至不需要管理它。 感谢您的帮助。 Python,lambda,找到最小值


我用我的foreach函数是这样的:

o.foreach(lambda i: i.call()) 

o.foreach(I.call) 

我不喜欢做一个列表或其他物体。我想通过迭代找到最小值。

我设法写一个类,做的看法,但应该有一些更好的解决方案比:

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

好了,我想我的.foreach方法是非蟒蛇的想法。我应该做我的类迭代,因为所有的解决方案都基于列表,然后一切都会变得更容易。

在C#中,这样的lambda函数没有问题,所以我虽然那个python也是强大的。

+3

你可以请发表一些你到目前为止的代码示例吗? – csl 2009-10-27 22:39:08

+1

+1为可能作业标记 – 2009-10-27 23:24:42

回答

5

写作foreach方法不是很pythonic。你最好使它成为一个迭代器,以便它可以与标准的Python函数一起工作,如min

而不是写像这样的:

def foreach(self, f): 
    for d in self._data: 
     f(d) 

这样写:

def __iter__(self): 
    for d in self._data: 
     yield d 

现在,您可以拨打minmin(myobj)

+0

但是,当我中断迭代并重新启动它时,它是如何工作的? 它从开始或从它被打破的那一刻开始? – qba 2009-10-28 10:54:19

+0

它再次调用'__iter__'函数,并在整个数据上返回一个新的迭代器。 – 2009-10-28 12:58:33

12

Python已经内置support for finding minimums

>>> min([1, 2, 3]) 
1 

如果您需要首先处理与功能的列表,你可以做到这一点与map

>>> def double(x): 
... return x * 2 
... 
>>> min(map(double, [1, 2, 3])) 
2 

或者你可以得到花哨例如:list comprehensionsgenerator expressions,例如:

>>> min(double(x) for x in [1, 2, 3]) 
2 
1

好吧,您需要了解的一件事:lambda为您创建了一个函数对象。但普通的普通def也是如此。看看这个例子:

lst = range(10) 

print filter(lambda x: x % 2 == 0, lst) 

def is_even(x): 
    return x % 2 == 0 

print filter(is_even, lst) 

这两个工作。它们产生相同的结果。 lambda生成一个未命名的函数对象; def生成一个命名的函数对象。 filter()并不关心函数对象是否有名称。

所以,如果你有lambda唯一的问题是,你不能在lambda使用=,你可以让使用def功能。

现在,这就是说,我不建议您使用.foreach()方法来找到最小值。相反,使主对象返回一个值列表,只需调用Python的min()函数即可。

lst = range(10) 
print min(lst) 

编辑:我同意,这是公认的答案是更好的。与其返回值列表,最好定义__iter__()并使对象可迭代。

0

假设你有

>>> seq = range(-4,4) 
>>> def f(x): 
... return x*x-2 

为x的值在最低

>>> min(seq, key=f) 
0 

当然,你可以使用拉姆达也

F的

>>> min(f(x) for x in seq) 
-2 

最小值

>>> min((lambda x:x*x-2)(x) for x in range(-4,4)) 
-2 

,但就是有点丑,地图看起来更好地在这里

>>> min(map(lambda x:x*x-2, seq)) 
-2 

>>> min(seq,key=lambda x:x*x-2) 
0 
1

我有它含有

这听起来每一个元素调用指定的函数,在征求意见的foreach功能你随后发布,你已经重新发明了内置的map函数。

这听起来像你正在寻找的东西是这样的:

min(map(f, seq)) 

其中f是要在列表中的每一项调用函数。

由于gnibbler显示,如果你想找到这f(x)返回的最低值序列中的值x,你可以使用:

min(seq, key=f) 

...除非你想找到的所有seq中的项目f返回最低值。举例来说,如果seq是字典列表,

min(seq, key=len) 

将返回第一个词典列表中的项目,而不是包含数项的所有词典的最小数量。

要获得序列中的所有项目,其f返回最小值的功能,这样做的一个列表:

values = map(f, seq) 
result = [seq[i] for (i, v) in enumerate(values) if v == min(values)] 
+0

您应该在列表理解前仅评估一次,而不是在列表理解中的每次迭代中对它进行评估。除此之外,这是一个很好的答案。 – blubberdiblub 2014-04-18 08:58:24

6

你不能用foreach和拉姆达做到这一点。如果你想以功能性的风格做到这一点,而不用实际使用min,你会发现reduce非常接近你想要定义的功能。

l = [5,2,6,7,9,8] 
reduce(lambda a,b: a if a < b else b, l[1:], l[0])