6 Stimmen

Python, lambda, Minimum finden

Ich habe foreach-Funktion, die angegebene Funktion auf jedes Element, das es enthält, aufruft. Ich möchte Minimum von diesen Elementen zu erhalten, aber ich habe keine Ahnung, wie Lambda oder Funktion oder sogar eine Klasse zu schreiben, die das verwalten würde. Danke für jede Hilfe.


Ich verwende meine foreach-Funktion wie folgt:

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

ou

o.foreach( I.call )

Ich mag es nicht, Listen oder andere Objekte zu erstellen. Ich möchte es durchlaufen und min finden.

Ich habe es geschafft, eine Klasse zu schreiben, die das Denken übernimmt, aber es sollte eine bessere Lösung als diese geben:

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 nehme ich an, dass meine .foreach-Methode nicht Python Idee ist. Ich sollte meine Klasse iterable tun, weil alle Ihre Lösungen auf Listen basieren und dann wird alles einfacher werden.

In C# gäbe es kein Problem mit solchen Lambda-Funktionen, also dachte ich, dass Python auch so mächtig ist.

13voto

Ryan Bright Punkte 3417

Python hat eingebaute Unterstützung bei der Suche nach Minimalwerten :

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

Wenn Sie die Liste zunächst mit einer Funktion bearbeiten müssen, können Sie dies mit Karte :

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

Oder Sie können sich etwas einfallen lassen mit Listenauffassungen y Generatorausdrücke zum Beispiel:

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

7voto

Chuck Punkte 228137

Sie können dies nicht tun mit foreach und ein Lambda. Wenn Sie dies in einem funktionalen Stil tun wollen, ohne tatsächlich min finden Sie reduce kommt der Funktion, die Sie zu definieren versuchten, ziemlich nahe.

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

5voto

Anand Chitipothu Punkte 3814

Schreiben foreach Methode ist nicht sehr pythonisch. Sie sollten sie besser zu einem Iterator machen, damit sie mit Standard-Python-Funktionen wie min .

Anstatt etwas wie dieses zu schreiben:

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

schreiben Sie dies:

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

Jetzt können Sie anrufen min como min(myobj) .

1voto

steveha Punkte 70950

Okay, eine Sache müssen Sie verstehen: lambda erstellt ein Funktionsobjekt für Sie. Aber das gilt auch für einfache, gewöhnliche def . Sehen Sie sich dieses Beispiel an:

lst = range(10)

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

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

print filter(is_even, lst)

Beides funktioniert. Sie führen zu demselben Ergebnis. lambda macht ein unbenanntes Funktionsobjekt; def macht ein benanntes Funktionsobjekt. filter() kümmert sich nicht darum, ob das Funktionsobjekt einen Namen hat oder nicht.

Wenn also Ihr einziges Problem mit lambda ist, dass Sie nicht mit = in einem lambda können Sie einfach eine Funktion erstellen, die def .

Trotzdem empfehle ich nicht, dass Sie Ihre .foreach() Methode, um einen Mindestwert zu finden. Lassen Sie stattdessen Ihr Hauptobjekt eine Liste von Werten zurückgeben, und rufen Sie einfach die Python min() Funktion.

lst = range(10)
print min(lst)

EDIT: Ich stimme zu, dass die akzeptierte Antwort besser ist. Anstatt eine Liste von Werten zurückzugeben, ist es besser, zu definieren __iter__() und machen das Objekt iterierbar.

1voto

Robert Rossney Punkte 91100

Ich habe foreach-Funktion, die angegebene Funktion auf jedes Element, das es enthält, aufruft

Aus Ihrem anschließenden Kommentar geht hervor, dass Sie das eingebaute System neu erfunden haben. map Funktion.

Es hört sich an, als ob Sie nach so etwas suchen:

min(map(f, seq))

donde f ist die Funktion, die Sie für jeden Eintrag in der Liste aufrufen möchten.

Wie gnibbler zeigt, kann man, wenn man den Wert x in der Reihenfolge, für die f(x) gibt den niedrigsten Wert zurück, den Sie verwenden können:

min(seq, key=f)

...es sei denn, Sie wollen alle der Artikel in seq bei denen f gibt den niedrigsten Wert zurück. Zum Beispiel, wenn seq ist eine Liste von Wörterbüchern,

min(seq, key=len)

gibt das erste Wörterbuch in der Liste mit der kleinsten Anzahl von Einträgen zurück, nicht alle Wörterbücher, die diese Anzahl von Einträgen enthalten.

Um eine Liste aller Elemente in einer Sequenz zu erhalten, für die die Funktion f den kleinsten Wert zurückgibt, tun Sie dies:

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X