2017-01-06 13 views
0
#!/usr/bin/env python2.7 

    import vobject 

    abinfile='/foo/bar/dir/infile.vcf' #ab stands for address book 

    aboutfile='/foo/bar/dir/outfile.vcf' 

    def eliminate_vcard_duplicates (abinfile, aboutfile): 

     #we first convert the Adrees Book IN FILE into a list 

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

     #then add each vcard from that list in a new list unless it's already there 

     ablist_norepeats=[] 
     ablist_norepeats.append(ablist[0]) 

     for i in range(1, len(ablist)): 
      jay=len(ablist_norepeats) 
      for j in reversed(range(0, jay)): #we do reversed because usually cards have duplicates nearby 
       if ablist_norepeats[j].serialize() == ablist[i].serialize(): 
        break 
       else: 
        jay += -1 
      if jay == 0: 
       ablist_norepeats.append(ablist[i]) 

     #and finally write the singularized list to the Adrees Book OUT FILE 

     with open(aboutfile, 'w') as destination_file: 
      for j in range(0, len(ablist_norepeats)): 
       destination_file.write(ablist_norepeats[j].serialize) 

    eliminate_vcard_duplicates(abinfile, aboutfile) 

위 코드는 작동하지 않으며 정확한 중복이없는 새 파일을 만듭니다 (동일한 단일화로 중복). 코드에 몇 가지 효율성 문제가 있다는 것을 알고 있습니다. n * log n이 될 수있는 경우 n 제곱입니다. 우리는 각 vacard를 한 번만 serialize 할 수 있습니다. 비효율적 인 사용 등. 여기서 해결 방법을 모르는 문제 중 하나를 설명하기 위해 짧은 코드를 제공하고자했습니다.vcf 파일에 대한 파이썬 코드 vcf 파일에서 중복 제거는 "정확한 중복"에만 적용됩니다.

우아하게 해결하는 방법이 확실하지 않은 문제는 다음과 같습니다. 일부가 인 경우 카드의 입력란이 뒤섞여있어 동등하지 않습니다. vobject, re 또는 다른 접근법으로 그러한 중복을 탐지하는 방법이 있습니까?

BEGIN:VCARD 
    VERSION:3.0 
    FN:Foo_bar1 
    N:;Foo_bar1;;; 
    EMAIL;TYPE=INTERNET:[email protected] 
    TEL;TYPE=CELL:123456789 
    TEL;TYPE=CELL:987654321 
    END:VCARD 
    BEGIN:VCARD 
    VERSION:3.0 
    FN:Foo_bar1 
    N:;Foo_bar1;;; 
    EMAIL;TYPE=INTERNET:[email protected] 
    TEL;TYPE=CELL:123456789 
    TEL;TYPE=CELL:987654321 
    END:VCARD 
    BEGIN:VCARD 
    VERSION:3.0 
    FN:Foo_bar1 
    N:;Foo_bar1;;; 
    TEL;TYPE=CELL:123456789 
    TEL;TYPE=CELL:987654321 
    EMAIL;TYPE=INTERNET:[email protected] 
    END:VCARD 
    BEGIN:VCARD 
    VERSION:3.0 
    FN:Foo_bar1 
    N:;Foo_bar1;;; 
    TEL;TYPE=CELL:987654321 
    TEL;TYPE=CELL:123456789 
    EMAIL;TYPE=INTERNET:[email protected] 
    END:VCARD 

위의 코드는 네 가지가 감지되지 않습니다이며,이 1-4 동일한 vCard를 테스트에 사용

파일 내용 (스크램블 생각을 이메일을 보내하지 전화 코드를 망쳐 놨을 스크램블) 마지막 하나는 전화 번호가 뒤섞이기 때문에 모두 똑같습니다.

보너스 포인트로, 누군가가 더 빠른 알고리즘을 갖고 있다면 공유가 가능할 것입니다. 위의 사람은 ... 오직 정확한 중복을 제거 않습니다 아직 ... 30.000 vCard 파일에

답변

0

다음은 빠른 코드되어 다음 (크기의 약 3 주문) 일이 소요되지만

#!/usr/bin/env python2.7 

    import vobject 
    import datetime 

    abinfile='/foo/bar/dir/infile.vcf' #ab stands for address book 

    aboutfile='/foo/bar/dir/outfile.vcf' 

    def eliminate_vcard_duplicatesv2(abinfile, aboutfile): 

     #we first convert the Adrees Book IN FILE into a list 
     ablist=[] 
     with open(abinfile) as source_file: 
      ablist = list(vobject.readComponents(source_file)) 

     #we then serialize the list to expedite comparison process 
     ablist_serial=[] 
     for i in range(0, len(ablist)): 
      ablist_serial.append(ablist[i].serialize()) 

     #then add each unique vcard's position from that list in a new list unless it's already there 
     ablist_singletons=[] 
     duplicates=0 
     for i in range(1, len(ablist_serial)): 
      if i % 1000 == 0: 
       print "COMPUTED CARD:", i, "Number of duplicates: ", duplicates, "Current time:", datetime.datetime.now().time() 
      jay=len(ablist_singletons) 
      for j in reversed(range(0, jay)): #we do reversed because usually cards have duplicates nearby 
       if ablist_serial[ablist_singletons[j]] == ablist_serial[i]: 
        duplicates += 1 
        break 
       else: 
        jay += -1 
      if jay == 0: 
       ablist_singletons.append(i) 

     print "Length of Original Vcard File: ", len(ablist) 
     print "Length of Singleton Vcard File: ", len(ablist_singletons) 
     print "Generating Singleton Vcard file and storing it in: ", aboutfile 

     #and finally write the singularized list to the Adrees Book OUT FILE 
     with open(aboutfile, 'w') as destination_file: 
      for k in range(0, len(ablist_singletons)): 
       destination_file.write(ablist_serial[ablist_singletons[k]]) 

    eliminate_vcard_duplicatesv2(abinfile, aboutfile)