Suche…


Holen Sie sich das Minimum oder Maximum von mehreren Werten

min(7,2,1,5)
# Output: 1

max(7,2,1,5)
# Output: 7

Verwenden Sie das Schlüsselargument

Das Finden des Minimums / Maximums einer Sequenz von Sequenzen ist möglich:

list_of_tuples = [(0, 10), (1, 15), (2, 8)]
min(list_of_tuples)
# Output: (0, 10)

Wenn Sie jedoch in jeder Sequenz nach einem bestimmten Element sortieren möchten, verwenden Sie das key -argument:

min(list_of_tuples, key=lambda x: x[0])         # Sorting by first element
# Output: (0, 10)

min(list_of_tuples, key=lambda x: x[1])         # Sorting by second element
# Output: (2, 8)

sorted(list_of_tuples, key=lambda x: x[0])      # Sorting by first element (increasing)
# Output: [(0, 10), (1, 15), (2, 8)]

sorted(list_of_tuples, key=lambda x: x[1])      # Sorting by first element
# Output: [(2, 8), (0, 10), (1, 15)]

import operator   
# The operator module contains efficient alternatives to the lambda function
max(list_of_tuples, key=operator.itemgetter(0)) # Sorting by first element
# Output: (2, 8)

max(list_of_tuples, key=operator.itemgetter(1)) # Sorting by second element
# Output: (1, 15)

sorted(list_of_tuples, key=operator.itemgetter(0), reverse=True) # Reversed (decreasing)
# Output: [(2, 8), (1, 15), (0, 10)]

sorted(list_of_tuples, key=operator.itemgetter(1), reverse=True) # Reversed(decreasing)
# Output: [(1, 15), (0, 10), (2, 8)]

Default Argument auf max, min

Sie können keine leere Sequenz in max oder min :

min([])

ValueError: min () arg ist eine leere Sequenz

Mit Python 3 können Sie jedoch das Schlüsselwortargument default mit einem Wert übergeben, der zurückgegeben wird, wenn die Sequenz leer ist, anstatt eine Ausnahme auszulösen:

max([], default=42)        
# Output: 42
max([], default=0)        
# Output: 0

Sonderfall: Wörterbücher

Das Ermitteln des Minimums oder Maximums oder die Verwendung der sorted hängt von den Iterationen des Objekts ab. Bei dict erfolgt die Iteration nur über den Tasten:

adict = {'a': 3, 'b': 5, 'c': 1}
min(adict)
# Output: 'a'
max(adict)
# Output: 'c'
sorted(adict)
# Output: ['a', 'b', 'c']

Um die Wörterbuchstruktur .items() , müssen Sie die .items() :

min(adict.items())
# Output: ('a', 3)
max(adict.items())
# Output: ('c', 1)
sorted(adict.items())
# Output: [('a', 3), ('b', 5), ('c', 1)]

Für sorted , können Sie eine erstellen OrderedDict die Sortierung zu halten , während eine mit dict -ähnlichen Struktur:

from collections import OrderedDict
OrderedDict(sorted(adict.items()))
# Output: OrderedDict([('a', 3), ('b', 5), ('c', 1)])
res = OrderedDict(sorted(adict.items()))
res['a']
# Output: 3

Nach Wert

Dies ist wiederum mit dem key möglich:

min(adict.items(), key=lambda x: x[1])
# Output: ('c', 1)
max(adict.items(), key=operator.itemgetter(1))
# Output: ('b', 5)
sorted(adict.items(), key=operator.itemgetter(1), reverse=True)
# Output: [('b', 5), ('a', 3), ('c', 1)]

Eine sortierte Reihenfolge erhalten

Verwendung einer Sequenz:

sorted((7, 2, 1, 5))                 # tuple
# Output: [1, 2, 5, 7]

sorted(['c', 'A', 'b'])              # list
# Output: ['A', 'b', 'c']

sorted({11, 8, 1})                   # set
# Output: [1, 8, 11]

sorted({'11': 5, '3': 2, '10': 15})  # dict
# Output: ['10', '11', '3']          # only iterates over the keys

sorted('bdca')                       # string
# Output: ['a','b','c','d']

Das Ergebnis ist immer eine neue list . Die ursprünglichen Daten bleiben unverändert.

Minimum und Maximum einer Sequenz

Das Minimum einer Sequenz (iterierbar) zu erhalten, entspricht dem Zugriff auf das erste Element einer sorted Sequenz:

min([2, 7, 5])
# Output: 2
sorted([2, 7, 5])[0]
# Output: 2

Das Maximum ist etwas komplizierter, weil sorted die Reihenfolge hält und max den zuerst gefundenen Wert zurückgibt. Falls keine Duplikate vorhanden sind, entspricht das Maximum dem letzten Element der sortierten Rückgabe:

max([2, 7, 5])
# Output: 7
sorted([2, 7, 5])[-1]
# Output: 7

Nicht jedoch, wenn mehrere Elemente mit dem Maximalwert bewertet werden:

class MyClass(object):
    def __init__(self, value, name):
        self.value = value
        self.name = name
        
    def __lt__(self, other):
        return self.value < other.value
    
    def __repr__(self):
        return str(self.name)

sorted([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')])
# Output: [second, first, third]
max([MyClass(4, 'first'), MyClass(1, 'second'), MyClass(4, 'third')])
# Output: first

Jede Iteration, die Elemente enthält, die < oder > Operationen unterstützen, ist zulässig.

Machen Sie benutzerdefinierte Klassen bestellbar

min , max und sorted alle Objekte bestellbar sein. Um korrekt bestellbar zu sein, muss die Klasse alle 6 Methoden __lt__ , __gt__ , __ge__ , __le__ , __ne__ und __eq__ :

class IntegerContainer(object):
    def __init__(self, value):
        self.value = value
        
    def __repr__(self):
        return "{}({})".format(self.__class__.__name__, self.value)
    
    def __lt__(self, other):
        print('{!r} - Test less than {!r}'.format(self, other))
        return self.value < other.value
    
    def __le__(self, other):
        print('{!r} - Test less than or equal to {!r}'.format(self, other))
        return self.value <= other.value

    def __gt__(self, other):
        print('{!r} - Test greater than {!r}'.format(self, other))
        return self.value > other.value

    def __ge__(self, other):
        print('{!r} - Test greater than or equal to {!r}'.format(self, other))
        return self.value >= other.value

    def __eq__(self, other):
        print('{!r} - Test equal to {!r}'.format(self, other))
        return self.value == other.value

    def __ne__(self, other):
        print('{!r} - Test not equal to {!r}'.format(self, other))
        return self.value != other.value

Die Implementierung all dieser Methoden erscheint zwar unnötig, aber einige davon wegzulassen, führt dazu, dass Ihr Code anfällig für Fehler wird .

Beispiele:

alist = [IntegerContainer(5), IntegerContainer(3),
         IntegerContainer(10), IntegerContainer(7)
        ]

res = max(alist)
# Out: IntegerContainer(3) - Test greater than IntegerContainer(5)
#      IntegerContainer(10) - Test greater than IntegerContainer(5)
#      IntegerContainer(7) - Test greater than IntegerContainer(10)
print(res)
# Out: IntegerContainer(10)

res = min(alist)   
# Out: IntegerContainer(3) - Test less than IntegerContainer(5)
#      IntegerContainer(10) - Test less than IntegerContainer(3)
#      IntegerContainer(7) - Test less than IntegerContainer(3)
print(res)
# Out: IntegerContainer(3)

res = sorted(alist)
# Out: IntegerContainer(3) - Test less than IntegerContainer(5)
#      IntegerContainer(10) - Test less than IntegerContainer(3)
#      IntegerContainer(10) - Test less than IntegerContainer(5)
#      IntegerContainer(7) - Test less than IntegerContainer(5)
#      IntegerContainer(7) - Test less than IntegerContainer(10)
print(res)
# Out: [IntegerContainer(3), IntegerContainer(5), IntegerContainer(7), IntegerContainer(10)]

mit reverse=True sorted reverse=True verwendet auch __lt__ :

res = sorted(alist, reverse=True)
# Out: IntegerContainer(10) - Test less than IntegerContainer(7)
#      IntegerContainer(3) - Test less than IntegerContainer(10)
#      IntegerContainer(3) - Test less than IntegerContainer(10)
#      IntegerContainer(3) - Test less than IntegerContainer(7)
#      IntegerContainer(5) - Test less than IntegerContainer(7)
#      IntegerContainer(5) - Test less than IntegerContainer(3)
print(res)
# Out: [IntegerContainer(10), IntegerContainer(7), IntegerContainer(5), IntegerContainer(3)]

sorted kann __gt__ stattdessen __gt__ verwenden, wenn der Standard nicht implementiert ist:

del IntegerContainer.__lt__   # The IntegerContainer no longer implements "less than"

res = min(alist) 
# Out: IntegerContainer(5) - Test greater than IntegerContainer(3)
#      IntegerContainer(3) - Test greater than IntegerContainer(10)
#      IntegerContainer(3) - Test greater than IntegerContainer(7)
print(res)
# Out: IntegerContainer(3)

Sortiermethoden TypeError einen TypeError wenn weder __lt__ noch __gt__ implementiert sind:

del IntegerContainer.__gt__   # The IntegerContainer no longer implements "greater then"

res = min(alist) 

TypeError: nicht anordnungsfähige Typen: IntegerContainer () <IntegerContainer ()


functools.total_ordering Dekorator functools.total_ordering kann verwendet werden, um die Erstellung dieser umfangreichen Vergleichsmethoden zu vereinfachen. Wenn Sie Ihre Klasse mit total_ordering , müssen Sie __eq__ , __ne__ und nur eines von __lt__ , __le__ , __ge__ oder __gt__ . Der Dekorateur füllt den Rest aus:

import functools

@functools.total_ordering
class IntegerContainer(object):
    def __init__(self, value):
        self.value = value
        
    def __repr__(self):
        return "{}({})".format(self.__class__.__name__, self.value)
    
    def __lt__(self, other):
        print('{!r} - Test less than {!r}'.format(self, other))
        return self.value < other.value
    
    def __eq__(self, other):
        print('{!r} - Test equal to {!r}'.format(self, other))
        return self.value == other.value
    
    def __ne__(self, other):
        print('{!r} - Test not equal to {!r}'.format(self, other))
        return self.value != other.value


IntegerContainer(5) > IntegerContainer(6)
# Output: IntegerContainer(5) - Test less than IntegerContainer(6)
# Returns: False

IntegerContainer(6) > IntegerContainer(5)
# Output: IntegerContainer(6) - Test less than IntegerContainer(5)
# Output: IntegerContainer(6) - Test equal to IntegerContainer(5)
# Returns True

Beachten Sie, wie die > ( größer als ) jetzt die Methode less als und in einigen Fällen sogar die Methode __eq__ . Das bedeutet auch, dass, wenn Geschwindigkeit von großer Bedeutung ist, Sie jede ausführliche Vergleichsmethode selbst implementieren sollten.

Extrahieren von N größten oder N kleinsten Elementen aus einer iterierbaren

Um eine bestimmte Anzahl (mehr als einen) der größten oder kleinsten Werte einer Iteration zu finden, können Sie die nlargest und nsmallest des heapq Moduls verwenden:

import heapq

# get 5 largest items from the range

heapq.nlargest(5, range(10))
# Output: [9, 8, 7, 6, 5]

heapq.nsmallest(5, range(10))
# Output: [0, 1, 2, 3, 4]

Dies ist viel effizienter, als das gesamte Iterable zu sortieren und dann am Ende oder Anfang zu schneiden. Intern verwenden diese Funktionen die Datenstruktur der binären Heap- Prioritätswarteschlange , die für diesen Anwendungsfall sehr effizient ist.

Wie min , max und sorted akzeptieren diese Funktionen das optionale key , das eine Funktion sein muss, die bei einem Element seinen Sortierschlüssel zurückgibt.

Hier ist ein Programm, das 1000 längste Zeilen aus einer Datei extrahiert:

import heapq
with open(filename) as f:
    longest_lines = heapq.nlargest(1000, f, key=len)

Hier öffnen wir die Datei und übergeben das nlargest f an nlargest . Durch die Iteration der Datei wird jede Zeile der Datei als separate Zeichenfolge angezeigt. nlargest dann jedes Element (oder jede Zeile) an die Funktion len , um den Sortierschlüssel zu bestimmen. len Angabe einer Zeichenfolge gibt len die Länge der Zeile in Zeichen zurück.

Dies erfordert nur Speicherplatz für eine Liste von 1000 größten Zeilen, die mit denen verglichen werden können

longest_lines = sorted(f, key=len)[1000:]

die muss die gesamte Datei im Speicher halten .



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow