Чтобы удалить дубликаты контактов vcard, сравнение, если две vcards равны в файле.vcf, не работает с простым == vobject сравнением

    #!/usr/bin/env python2.7 

    import vobject

    abfile='/foo/bar/directory/file.vcf' #ab stands for address book  

    ablist = []

    with open(abfile) as source_file:
        for vcard in vobject.readComponents(source_file):
          ablist.append(vcard)         

    print ablist[0]==ablist[1]

Приведенный выше код должен возвращать True, но это не так, потому что vcards считаются разными, даже если они одинаковы. Одна из конечных целей - найти способ удалить дубликаты из файла vcard. Бонусные баллы: есть ли способ сделать сравнение совместимым с использованием одного из быстрых способов унификации списка в Python, таких как:

    set(ablist) 

удалить дубликаты? (например, конвертировать vcards в строки как-то...). В приведенном выше коде len(set(ablist)) возвращает 2, а не 1, как ожидалось...

Напротив, если вместо сравнения всей карты, мы сравниваем один ее компонент, как в:

    print ablist[0].fn==ablist[1].fn

тогда мы видим ожидаемое поведение и получаем True как ответ...

Вот содержимое файла, использованное в тесте (только с двумя одинаковыми визитками):

    BEGIN:VCARD
    VERSION:3.0
    FN:Foo_bar1
    N:;Foo_bar1;;;
    EMAIL;TYPE=INTERNET:foobar1@foo.bar.com
    END:VCARD
    BEGIN:VCARD
    VERSION:3.0
    FN:Foo_bar1
    N:;Foo_bar1;;;
    EMAIL;TYPE=INTERNET:foobar1@foo.bar.com
    END:VCARD

2 ответа

Решение

@ Брайан Барселона, относительно вашего ответа, просто чтобы вы знали, вместо:

ablist = []

with open(abfile) as source_file:
    for vcard in vobject.readComponents(source_file):
      ablist.append(vcard)

Вы могли бы сделать:

with open(abfile) as source_file:
    ablist = list(vobject.readComponents(source_file))

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

Я обнаружил, что будет работать следующее - понимание заключается в том, чтобы "serialize()" vcard:

#!/usr/bin/env python2.7 

import vobject

abfile='/foo/bar/directory/file.vcf' #ab stands for address book  

ablist = []

with open(abfile) as source_file:
    for vcard in vobject.readComponents(source_file):
      ablist.append(vcard)         

print ablist[0].serialize()==ablist[1].serialize()

Однако должен быть лучший способ сделать это... любая помощь будет приветствоваться!

Другие вопросы по тегам