要删除vcard联系人重复项,比较.vcf文件中两个vcards是否相等不适用于简单的== vobject比较

时间:2017-01-04 09:12:36

标签: python-2.7 comparison vcard 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 ......

相反,如果不是比较整个vcard,我们将它的一个组成部分比作:

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

然后我们确实看到了预期的行为,并收到True作为回应...

以下是测试中使用的文件内容(只有两个相同的vcards):

    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 个答案:

答案 0 :(得分:1)

@Brian巴塞罗那,关于你的回答,只是为了让你知道,而不是:

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的不同组件可能是相同的但不是相同的顺序。我认为最好的方法是自己检查每个相关组件。

答案 1 :(得分:0)

我发现以下内容可行 - 洞察力是"序列化()" 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()

然而,应该有更好的方法来做到这一点......任何帮助都会受到欢迎!