2009-08-01 5 views
2

Ich möchte ein Element zu einer Liste hinzufügen, die die Reihenfolge der Liste beibehalten.ist es möglich, ein Element zu einer Liste hinzuzufügen und die Reihenfolge beizubehalten

Lassen Sie uns die Liste der Objektnehmen ist [a, b, c, d] I eine Funktion cmp haben, die zwei Elemente der Liste vergleicht. Wenn ich ein f-Objekt hinzufüge, das größer ist, möchte ich, dass es an der letzten Position ist.

vielleicht ist es besser, die komplette Liste zu sortieren ...

Antwort

4

bisect.insort ist ein wenig schneller, gegebenenfalls als anhängen-then-Art (es sei denn, Sie haben ein paar Elemente hinzufügen, bevor Sie die Liste müssen wieder sortiert werden) - wie üblich auf meinem Laptop Mess (a zügigere Maschine wird natürlich schneller auf der ganzen Linie, aber das Verhältnis sollte in etwa konstant bleiben):

$ python -mtimeit -s'import random, bisect; x=range(20)' 'y=list(x); bisect.insort(y, 22*random.random())' 
1000000 loops, best of 3: 1.99 usec per loop 

vs

$ python -mtimeit -s'import random, bisect; x=range(20)' 'y=list(x); y.append(22*random.random()); y.sort()' 
100000 loops, best of 3: 2.78 usec per loop 

Wie viel man sich dafür interessieren Unterschied hängt natürlich davon ab, wie kritisch ein Engpass diese Operation für Ihre Anwendung ist - es gibt natürlich Situationen, in denen selbst dieser Bruchteil einer Mikrosekunde den Unterschied macht, obwohl sie die Ausnahme, nicht die Regel sind.

Das bisect Modul ist nicht so flexibel und konfigurierbar - Sie können ganz einfach Ihre eigenen Komparator passieren (obwohl zu sortieren, wenn Sie möglicherweise in Form eines Schlüssels = Argument setzen Sie sind stark geraten zu tun das, in Python 3 bleibt nur key =, cmp = ist weg, weil die Leistung einfach nicht gut gemacht werden konnte, während bisect steif integrierte Vergleiche verwendet (also müssten Sie Ihre Objekte in Wrapper umwandeln, die __cmp__ implementieren oder __le__ nach Ihren Wünschen, was auch wichtige Auswirkungen auf die Leistung hat).

In Ihren Schuhen würde ich mit dem Append-Though-Sort-Ansatz beginnen und nur dann zum weniger handlichen Halbierungs-Ansatz wechseln, wenn das Profiling zeigt, dass der Performance-Hit wesentlich ist. Denken Sie daran, Knuth's (und Hoares) berühmten Zitat, und Kent Beck's fast-wie-berühmten auch zu! -)

5

Ja, das ist es, was bisect.insort für ist, aber es nicht eine Vergleichsfunktion übernehmen. Wenn es sich bei den Objekten um benutzerdefinierte Objekte handelt, können Sie eines oder mehrere der rich comparison methods überschreiben, um die gewünschte Sortierreihenfolge festzulegen. Oder Sie könnten ein 2-Tupel mit dem Sortierschlüssel als erstes Element speichern und stattdessen sortieren.

0
L.insert(index, object) -- insert object before index 
Verwandte Themen