Python проверяет, находится ли объект в списке объектов

У меня есть список объектов в Python. Затем у меня есть еще один список объектов. Я хочу просмотреть первый список и посмотреть, появятся ли какие-либо элементы во втором списке.

Я думал, что могу просто сделать

for item1 in list1:
    for item2 in list2:
        if item1 == item2:
            print "item %s in both lists"

Однако это не работает. Хотя, если я это сделаю:

if item1.title == item2.title:

он работает нормально. У меня есть больше атрибутов, чем это, хотя я действительно не хочу делать 1 большой оператор if, сравнивающий все атрибуты, если мне не нужно.

Кто-нибудь может мне помочь или посоветовать, что я могу сделать, чтобы найти объекты, которые появляются в обоих списках.

Спасибо

Ответы

Ответ 1

Предполагая, что ваш объект имеет только атрибут title, который имеет отношение к равенству, вы должны реализовать метод __eq__ следующим образом:

class YourObject:
    [...]
    def __eq__(self, other):
        return self.title == other.title

Конечно, если у вас есть больше атрибутов, релевантных для равенства, вы должны также включить их. Вы также можете рассмотреть возможность реализации __ne__ и __cmp__ для обеспечения согласованного поведения.

Ответ 2

Если объекты не являются одним и тем же экземпляром, вам нужно реализовать метод __eq__ для python, чтобы он мог сказать, когда на самом деле равны 2 объекта.

Конечно, что большинство типов библиотек, таких как строки и списки, уже реализовано __eq__, что может быть причиной того, что для вас работает сравнение титров (это строки?).

Для получения дополнительной информации см. документацию python.
Вот случайный пример для __eq__.

Ответ 3

установить пересечение для этого.

>>> x=[1,2,3,4]
>>> y=[3,4,5,6]
>>> for i in set(x) & set(y):
...     print "item %d in both lists" %i
...
item 3 in both lists
item 4 in both lists

Ответ 4

Поиск объектов, которые отображаются в обоих списках:

l1 = [1,2,3,4,5]
l2 = [3,4,5]
common = set(l1).intersection(set(l2))

Объедините это с реализацией __eq__ объекта, как и другие.

Ответ 5

Вам нужно написать функцию __eq__, чтобы определить, как сравнивать объекты для равенства. Если вы хотите сортировать, то yo должна иметь функцию __cmp__, и имеет смысл реализовать __eq__ в терминах __cmp__.

def __eq__(self, other):
    return cmp(self, other) == 0

Вероятно, вы также должны реализовать __hash__, и вам обязательно нужно, если вы планируете помещать свои объекты в набор или словарь. По умолчанию __hash__ для объектов - id(), что фактически делает все объекты уникальными (то есть уникальность не основана на содержимом объекта).

Я написал базовый класс/интерфейс для класса, который выполняет подобное сравнение эквивалентности. Вы можете найти это полезным:

class Comparable(object):
    def attrs(self):
        raise Exception("Must be implemented in concrete sub-class!")
    def __values(self):
        return (getattr(self, attr) for attr in self.attrs())
    def __hash__(self):
        return reduce(lambda x, y: 37 * x + hash(y), self.__values(), 0)
    def __cmp__(self, other):
        for s, o in zip(self.__values(), other.__values()):
            c = cmp(s, o)
            if c:
                return c
        return 0
    def __eq__(self, other):
        return cmp(self, other) == 0
    def __lt__(self, other):
        return cmp(self, other) < 0
    def __gt__(self, other):
        return cmp(self, other) > 0

if __name__ == '__main__':
    class Foo(Comparable):
        def __init__(self, x, y):
            self.x = x
            self.y = y
        def attrs(self):
            return ('x', 'y')
        def __str__(self):
            return "Foo[%d,%d]" % (self.x, self.y)

    def foo_iter(x):
        for i in range(x):
            for j in range(x):
                yield Foo(i, j)

    for a in foo_iter(4):
        for b in foo_iter(4):
            if a<b: print "%(a)s < %(b)s" % locals()
            if a==b: print "%(a)s == %(b)s" % locals()
            if a>b: print "%(a)s > %(b)s" % locals()

Производный класс должен реализовать attrs(), который возвращает кортеж или список атрибутов объекта, которые способствуют его идентификации (т.е. неизменяющие атрибуты, которые делают его тем, чем он является). Самое главное, что код правильно обрабатывает эквивалентность, где есть несколько атрибутов, и это старый школьный код, который часто выполняется неправильно.

Ответ 6

matches = [x for x in listA if x in listB]

Ответ 7

Попробуйте следующее:

list1 = [item1, item2, item3]
list2 = [item3, item4, item5]
for item in list1:
    if item in list2:
        print "item %s in both lists" % item