要删除 vcard 联系人重复项,比较 .vcf 文件中的两个 vcard 是否相等不适用于简单 == vobject 比较
To remove vcard contact duplicates, comparing if two vcards are equal in .vcf file does not work with simple == vobject comparison
#!/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]
上面的代码应该 return 正确,但事实并非如此,因为即使 vcards 相同,也被认为是不同的。最终目标之一是找到一种从 vcard 文件中删除重复项的方法。奖励积分:有没有一种方法可以使比较与使用一种在 Python 中统一列表的快速方法兼容,例如:
set(ablist)
删除重复项? (例如,以某种方式将 vcards 转换为字符串......)。在上面的代码中 len(set(ablist)) returns 2 而不是预期的 1...
相比之下,如果不是比较整个 vcard,而是比较它的一个组成部分,如:
print ablist[0].fn==ablist[1].fn
然后我们确实看到了预期的行为并收到 True 作为响应...
以下是测试中使用的文件内容(只有两张相同的vcard):
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
我发现以下方法有效 - 洞察力是 "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()
但是,应该有更好的方法来做到这一点...欢迎任何帮助!
@Brian Barcelona,关于你的回答,只是想让你知道,而不是:
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 的不同组件可能相同但顺序不同。我认为最好的方法是您自己检查每个相关组件。
#!/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]
上面的代码应该 return 正确,但事实并非如此,因为即使 vcards 相同,也被认为是不同的。最终目标之一是找到一种从 vcard 文件中删除重复项的方法。奖励积分:有没有一种方法可以使比较与使用一种在 Python 中统一列表的快速方法兼容,例如:
set(ablist)
删除重复项? (例如,以某种方式将 vcards 转换为字符串......)。在上面的代码中 len(set(ablist)) returns 2 而不是预期的 1...
相比之下,如果不是比较整个 vcard,而是比较它的一个组成部分,如:
print ablist[0].fn==ablist[1].fn
然后我们确实看到了预期的行为并收到 True 作为响应...
以下是测试中使用的文件内容(只有两张相同的vcard):
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
我发现以下方法有效 - 洞察力是 "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()
但是,应该有更好的方法来做到这一点...欢迎任何帮助!
@Brian Barcelona,关于你的回答,只是想让你知道,而不是:
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 的不同组件可能相同但顺序不同。我认为最好的方法是您自己检查每个相关组件。