繁体   English   中英

高效地打印巨大的不同字符串列表的交集和并集

[英]Efficiently printing the intersection and union of huge different lists of strings

我有三个不同句子的列表:

第一个有(6228 个元素),第二个有(30177 个)元素,最后一个有(1059 个)元素。

每个列表中的字符串对应于 3 到超过 150 个字符的句子。 这些句子被提取并分离在不同的列表中,以便将它们写入不同的 .tsv 文件中。 所以现在我想在其中搜索以找到三个列表的常用句子以及它们之间的交集。

我想打印有双胞胎和没有双胞胎的三个列表的交集(因为 list_1 中的 somme elt 可以出现在 list_2 或 list_3 中。我还想打印每个列表与另一个列表之间的交集:

例如列表 1 和 2 中元素的交集,但不在列表 3 中; 列表 2 和 3 中但不在列表 1 中的元素; 和列表 3 & 1 中但不在列表 2 中的元素;

我想出了这个算法,但有没有更好的方法来获得我想要的东西? 我问是因为因为我正在处理长字符串(句子),我担心有时列表中的循环不是很有效,也没有给我带来准确的结果。 因为我的文件很大。 我给你这个小样本

    l_1 = ['je mange du pain', 'tu es laid', 'je suis beau', 'vive la vie', 'vive l\'horizon']
    l_2 =  ['je mange du pain', 'vive l\'horizon', 'L\'esprit des eaux est vaincu', 'Satan tu es vaincu', 'Jésus est puissant et t\'a vaincu', 'Satan tu n\'es rien' , 'tu ne peux pas m\'intimider', 'Je suis couverte par le Sang de Jésus']
    l_3 = ['je mange du pain', 'vive l\'horizon', 'L\'esprit des eaux est vaincu', 'Je suis couverte par le Sang de Jésus', 'vive la vie']

    sentences_1 = []    # intersection
    sentences_2_1 = []   # intersection between two list without checking if the elt is present the last list
    sentences_2_2 = []
    sentences_2_3 = []

    sentences_2_1_0 = []  intersection between two list with checking if the elt is present the last list
    sentences_2_2_0 = []
    sentences_2_3_0 = []
    sentences_3 = []      # Union of the three list (can contains sentences which are present more than once)

    #  One case
    for elt in l_2:
      if elt in l_1 and elt in l_3 :
        if elt not in sentences_1:
          sentences_1.append(elt)

    print('Phrases communes aux trois conditions :', len(sentences_1))


    # Second case 
    for elt in l_1:     
      if elt in l_2:
        if elt not in sentences_2_1_0:
          sentences_2_1_0.append(elt)

    print('Phrases communes aux sets 1 & 2 :', len(sentences_2_1_0))

    for elt in l_1:     
      if elt in l_2 and elt not in l_3:
        if elt not in sentences_2_1:
          sentences_2_1.append(elt)

    print('Phrases communes aux sets 1 & 2 mais pas 3:', len(sentences_2_1))


    # Second case 
    for elt in l_2:     
      if elt in l_3:
        if elt not in sentences_2_2_0:
          sentences_2_2_0.append(elt)

    print('Phrases communes aux sets 2 & 3 :', len(sentences_2_2_0))

    for elt in l_2:      
      if elt in l_3 and elt not in l_1 :
        if elt not in sentences_2_2:
            sentences_2_2.append(elt)

    print('Phrases communes aux sets 2 & 3 mais pas 1:', len(sentences_2_2))


    # Second case 
    for elt in l_3:     
      if elt in l_1 :
        if elt not in sentences_2_3_0:
          sentences_2_3_0.append(elt)

    print('Phrases communes aux sets 3 & 1 :', len(sentences_2_3_0))  

    for elt in l_1:
      if elt in l_3 and elt not in l_2 :
          if elt not in sentences_2_3:
            sentences_2_3.append(elt)

    print('Phrases communes aux sets 3 & 1 mais pas 2:', len(sentences_2_3))

    # third case 
    for elt in l_1:
      sentences_3.append(elt)

    for elt in l_2:
      sentences_3.append(elt)

    for elt in l_3: 
      sentences_3.append(elt)  
      #any(x, y, z) not in sentences_3:



    print('Union des trois sets:', len(sentences_3))

    sentences_3_filtered = sorted(list(set(sentences_3)))  # Print the union of the three list without doublon, we keep each sentences just once deleting doublons or triple

    print( "sans doublon :", len(sentences_3_filtered))

即使是 30177 个项目(每个 150 个字符的字符串)的列表也不是很大。

您可以直接使用集合,并执行您想要的任何交集逻辑:

a = set([<items>...])
b = set([<items>...])
c = set([<items>...])

然后,例如:

a_and_b = a & b
a_and_c_but_not_b = a & c - b  # order of operations wouldn't matter anyway

应该都非常快。

如果您有大量真正非常大的列表,首先在外部对它们进行排序,然后进行合并操作可以提供一些好处。

有两种方法可以做到这一点:首先使用 set 或 map。set 将是更明智的选择,因为它会节省空间。 其次,如果您正在处理的数据太大,您可能希望通过将其分成相等的部分来考虑并行处理。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM