Эффективная печать пересечения и объединения огромных различных списков строк - PullRequest
2 голосов
/ 26 мая 2020

У меня есть три списка различных предложений:

первый содержит (6228 элементов), второй (30177) элементов и последний (1059).

Строка в каждом списке соответствует предложениям от 3 до более чем 150 символов. Эти предложения были извлечены и разделены в разные списки, чтобы записать их в разные файлы .tsv. Итак, теперь я хочу поискать в них, чтобы найти общие предложения для трех списков, а также пересечение между ними.

Я хотел бы напечатать пересечение трех списков с дублоном и без него (потому что somme elt в list_1 может присутствовать в 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))

1 Ответ

1 голос
/ 26 мая 2020

Даже список из 30177 элементов (каждая строка из 150 символов) не очень большой.

Вы можете просто использовать наборы напрямую и делать любые пересечения logi c, которые захотите:

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

, все должно быть очень быстрым.

Если у вас действительно большое количество действительно очень больших списков, сначала отсортируйте их извне а затем выполнение операций слияния может дать некоторые преимущества.

...