Сохранение порядка при использовании разницы в настройках Python

Я делаю операцию разметки в Python:

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

Я получаю:

[ObjectId('4f7abaa043f1e51544000007'), ObjectId('4f7ac02543f1e51a44000001'), ObjectId('4f7aba8a43f1e51544000006')]

Мне нужно получить первый элемент для следующей операции, что важно. Как сохранить список x в исходном формате?

Ответ 1

Похоже, вам нужен упорядоченный набор вместо обычного набора.

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

Python не поставляется с упорядоченным набором, но его легко сделать:

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)

Надеюсь, что это поможет: -)

Ответ 2

Установки неупорядочены, поэтому вам нужно будет вернуть результаты в правильном порядке после выполнения заданной разницы. К счастью, у вас уже есть элементы в нужном порядке, так что это легко.

diff = set(x) - set(y)
result = [o for o in x if o in diff]

Но это может быть упорядочено; вы можете сделать разницу как часть понимания списка (хотя, возможно, немного менее ясно, что это то, что вы делаете).

sety = set(y)
result = [o for o in x if o not in sety]

Вы даже можете сделать это, не создавая set из y, но set обеспечит быстрые тесты на членство, что позволит сэкономить вам значительное время, если один из них большой.

Ответ 3

Вы могли бы просто сделать это

diff = set(x) - set(y)
[item for item in x if item in diff]

или

filter(diff.__contains__, x)