Beibehaltung der Reihenfolge bei Verwendung der Python-Differenz

Ich führe in Python eine Differenzierungsoperation durch:

<code>from sets import Set
from mongokit import ObjectId
x = [ObjectId("4f7aba8a43f1e51544000006"), ObjectId("4f7abaa043f1e51544000007"), ObjectId("4f7ac02543f1e51a44000001")]
y = [ObjectId("4f7acde943f1e51fb6000003")]
print list(Set(x).difference(Set(y)))
</code>

Ich erhalte:

<code>[ObjectId('4f7abaa043f1e51544000007'), ObjectId('4f7ac02543f1e51a44000001'), ObjectId('4f7aba8a43f1e51544000006')]
</code>

Ich muss das erste Element für die nächste Operation besorgen, was wichtig ist. Wie kann ich die Liste behalten?x im Originalformat?

 holdenweb15. März 2014, 19:14
Aber nicht so alt wie wir
 Raymond Hettinger04. Apr. 2012, 09:32
Dassets.Set Typ ist eine vernünftige Wahl für jemanden, der Kompatibilität mit älteren Versionen von Python benötigt. Das eingebauteeinstellen Typ wurde nachgebildetsets.Set - beide funktionieren gut für die meisten Anwendungen (obwohl die eingebaute Version schneller ist).
 icktoofay04. Apr. 2012, 07:28
Mengen sind per Definition ungeordnet.
 Thomas Wouters05. Apr. 2012, 01:08
Beachten Sie, dass "älter" "Python 2.3 oder früher" bedeutetziemlich viel älter.
 Chris Morgan04. Apr. 2012, 07:30
Und du solltest das niemals benutzensets Modul. Verwenden Sie das eingebauteset Art.

Antworten auf die Frage(3)

daher müssen Sie die Ergebnisse nach der Set-Differenzierung wieder in der richtigen Reihenfolge anzeigen. Glücklicherweise haben Sie die Elemente bereits in der von Ihnen gewünschten Reihenfolge, sodass dies einfach ist.

<code>diff = set(x) - set(y)
result = [o for o in x if o in diff]
</code>

Dies kann jedoch rationalisiert werden. Sie können den Unterschied als Teil des Listenverständnisses machen (obwohl es wohl etwas weniger klar ist, dass Sie das tun).

<code>sety = set(y)
result = [o for o in x if o not in sety]
</code>

Sie könnten es sogar tun, ohne das zu erstellenset vony, aber dieset bietet schnelle Mitgliedschaftstests, mit denen Sie erheblich Zeit sparen, wenn eine der Listen umfangreich ist.

 jamylak04. Apr. 2012, 08:21
nvm, dachte es muss schneller sein.
 kindall04. Apr. 2012, 18:22
Etwas schneller, ja. Es muss nur die Liste durchlaufen werdenx einmal statt zweimal.
 jamylak04. Apr. 2012, 08:05
Wenn Sie rationalisiert sagen, meinen Sie damit Leistung?

Sets.

<code>>>> x = [ObjectId("4f7aba8a43f1e51544000006"), ObjectId("4f7abaa043f1e51544000007"), ObjectId("4f7ac02543f1e51a44000001")]
>>> y = [ObjectId("4f7acde943f1e51fb6000003")]
>>> print list(OrderedSet(x) - OrderedSet(y))
[ObjectId("4f7aba8a43f1e51544000006"), ObjectId("4f7abaa043f1e51544000007"), ObjectId("4f7ac02543f1e51a44000001")]
</code>

Python wird nicht mit einem bestellten Set geliefert, aber es ist einfach, eines zu erstellen:

<code>import collections

class OrderedSet(collections.Set):

    def __init__(self, iterable=()):
        self.d = collections.OrderedDict.fromkeys(iterable)

    def __len__(self):
        return len(self.d)

    def __contains__(self, element):
        return element in self.d

    def __iter__(self):
        return iter(self.d)
</code>

Hoffe das hilft :-)

 Bruce Dean27. Juni 2018, 06:07
Du rockst, großartig.

Du könntest das einfach tun

<code>diff = set(x) - set(y)
[item for item in x if item in diff]
</code>

oder

<code>filter(diff.__contains__, x)
</code>
 jamylak04. Apr. 2012, 07:45
Ya das war nur eine Verwechslung mit Python 3, ich habe vergessen, ich sollte Python 2 verwenden, um SO Fragen zu beantworten, hatte es nur als Option für den Generator ... Weniger freundlich ... hmm ... nun, sie wurden nicht entfernt und Python hat eine Reihe nützlicher Dinge, die das Schreiben des Codes für kleine Dinge wie Map erleichtern. Wenn sie noch in Python sind, können wir sie noch verwenden.
 Dougal04. Apr. 2012, 08:02
Ihr Filter wäre dann etwas glatterfilter(diff.__contains__, x). Natürlich ist es äquivalent zu tunset_y = set(y); filter(lambda item: item not in set_y, x) auch. (Schade, dass Python keine hatnot das erhebt sich zu Funktionen oder dem "Gegenteil" vonfilter, oder das wäre schöner.)
 jamylak04. Apr. 2012, 07:50
Die Mine wurde aktualisiert, um das Ergebnis des Sets zu verarbeiten.
 Chris Morgan04. Apr. 2012, 07:40
Es ist etwas, dessen Leistung Sie überprüfen möchten.
 jamylak04. Apr. 2012, 07:42
Oh, richtig, ich habe vergessen, dass ich Python 3 verwendet habe. Ich werde es wieder ändern. Ich dachte, es wäre nützlich in Python 3 als Generator. Auch warum ist Filter nicht pythonisch?
 jamylak04. Apr. 2012, 07:39
In Ordnung, ich war mir nicht sicher, was die Geschwindigkeit angeht, aber wenn Sie sich sicher sind, dann denke ich, ist das am besten.
 Chris Morgan04. Apr. 2012, 07:41
Warum würden Sie jemals für die gehen?filter Ausführung? Nicht Pythonic. Auch dielist() Ein Wrapping würde es in Python 2, in dem eine Liste bereits von zurückgegeben wird, weniger effizient machenfilter().
 jamylak04. Apr. 2012, 08:09
Das würde funktionieren, wenn Sie den eingestellten Vorgang umkehren würden. Aber wird es nicht als schlechte Praxis angesehen, private Methoden anzuwenden?
 Chris Morgan04. Apr. 2012, 07:36
Und wenn Sie es mit einer großen Anzahl von Elementen iny oder viele Male arbeiten anset(y) eher, alsy kann schneller sein.
 Chris Morgan04. Apr. 2012, 07:43
Abgesehen davon, dass Sie es dann sofort in eine Liste aufnehmen, ist das Listenverständnis also genauso gut.filter und die anderen Funktionen wie diese stammen aus der funktionalen Programmierung; Für die allgemeine Programmierung in Python gelten sie als weniger benutzerfreundlich als Listenverständnisse oder Generatorausdrücke. In Python 3 wurde sogar darüber diskutiert, sie insgesamt zu entfernen.

Ihre Antwort auf die Frage