Python - проблема с циклами при сравнении двух списков - PullRequest
0 голосов
/ 14 июня 2019

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

Сначала я сделал этот маленький скрипт:

data1 = ['test', 'super', 'class', 'test', 'boom']
data2 = ['test', 'super', 'class', 'test', 'boom']
res = 0
nb = (len(data1) + len(data2)) / 2
if data1 and data2 and nb != 0:
    for id1, item1 in enumerate(data1):
        for id2, item2 in enumerate(data2):
            if item1 == item2:
                res += 1 - abs(id1 - id2) / nb
    print(res / nb * 100)

Проблема в том, что если у меня есть 2 раза одно и то же слово в списках, процент будет больше, чем 100%.Чтобы противостоять этому, я добавил 'break' сразу после строки 'res + = 1 - abs (id1 - id2) / nb', но процент все еще искажен.

Надеюсь, вы понимаете мойпроблема, спасибо тебе за помощь!

Ответы [ 3 ]

1 голос
/ 14 июня 2019

Вместо этого можно использовать difflib.SequenceMatcher, чтобы сравнить сходство двух списков.Попробуйте это:

from difflib import SequenceMatcher as sm
data1 = ['test', 'super', 'class', 'test', 'boom']
data2 = ['test', 'super', 'class', 'test', 'boom']
matching_percentage = sm(None, data1, data2).ratio() * 100

Вывод :

100.0
0 голосов
/ 14 июня 2019

Попробуйте этот код:

data1 = ['test', 'super', 'class', 'class', 'test', 'boom']
data2 = ['test', 'super', 'class', 'class', 'test', 'boom']
res = 0
nb = (len(data1) + len(data2)) / 2.0

def pos_iter(index, sz):
    yield index
    i1 = index - 1
    i2 = index + 1
    while i1 >=0 and i2 < sz:
        if i1 >= 0:
            yield i1
            i1 -=1
        if i2 < sz:
            yield i2
            i2 += 1
if data1 and data2 and nb != 0:
    for id1, item1 in enumerate(data1):
        for id2 in pos_iter(id1, len(data2)):
            item2 = data2[id2]
            if item1 == item2:
                res += max(0, 1 - abs(id1 - id2) / nb)
                break
    print(res / nb * 100)

Проблема с вашим кодом состоит в том, что вы ищете подходящее слово в секунду data2 всегда с начала.Что даст вам недопустимые значения, если слова повторяются.Вам нужно всегда искать «вокруг» положение слова в data1, потому что вы хотите найти самое близкое.

Также вам нужен разрыв, который вы добавили, иначе текст с теми же словами будет идтивыше 1,0.Ваша переменная nb должна быть двойной (или python2 округлит результат деления).И вы должны убедиться, что 1 - abs(id1 - id2) / nb больше нуля, поэтому я добавил max(0, ...).

0 голосов
/ 14 июня 2019
data1 = ['test', 'super', 'class', 'test', 'boom']
data2 = ['test', 'super', 'class', 'test', 'boom']
from collections import defaultdict

dic1 =defaultdict(int)
dic2=defaultdict(int)

for i in data1:
    dic1[i]+=1

for i in data2:
    dic2[i]+=1

count = 0

for i in dic1:
    if i in dic2.keys():
        count+=abs(dic2[i]-dic1[i])


result =( (1-count/(len(data1)+len(data2))) *100)

выход

100.0
...