比较多个 Python 列表并合并 Levenshtein 相似性
Compare multiple Python lists and merge on Levenshtein similarity
我写了一个 Python 函数,它接受两个列表,使用 Levenshtein 比较它们并将足够相似的单词合并到一个名为“merged”的列表中。
如何为 6 个以上的列表执行此操作?确保将每个列表与其他 5 个列表进行比较等等?
first_list = ["Mouse", "Cat", "Dog", "Gremlinge", "Horse"]
second_list = ["Mouse", "Cat", "Hors", "Dog", "Gremling"]
third_list = ["Mouse", "Cat", "Horrs", "Dog", "Greemling"]
fourth_list = ["Mouse", "Cate", "Dog", "Gremlinge", "Horse"]
fifth_list = ["Mose", "Cat", "Hors", "Dog", "Gremling"]
sixth_list = ["Mouse", "Cat", "Horser", "Doeg", "Gremling"]
def lev_merging(a, b): # function to compare 2 lists
merged = [] # Empty list to add the matching words
for first in a:
for second in b:
if levenshtein(first, second) < 2:
merged.append(set([first,second]))
return merged
print (lev_merging(first_list,second_list))
我们将得到一个字符串列表列表
list_of_lists = [["Mouse", "Cat", "Dog", "Gremlinge", "Horse"],
["Mouse", "Cat", "Hors", "Dog", "Gremling"],
["Mouse", "Cat", "Horrs", "Dog", "Greemling"],
["Mouse", "Cate", "Dog", "Gremlinge", "Horse"],
["Mose", "Cat", "Hors", "Dog", "Gremling"],
["Mouse", "Cat", "Horser", "Doeg", "Gremling"]]
然后我们将遍历此列表,跟踪我们所在列表的索引 "in",并将此列表与它之后的所有列表进行比较。
def merging(list_of_lists):
merged = []
for i, a in enumerate(list_of_lists):
for b in list_of_lists[i+1:]:
for first in a:
for second in b:
if lev(first, second) < 2:
merged.append((first, second))
return merged
编辑:下面的代码将成对的列表传递给一个函数,并将它们分成几组。然后我们将把这些组中的每一个处理成集合,以删除重复项。
target_num_words = 6
target_num_words
def merging(list_of_lists):
groups = []
for i, a in enumerate(list_of_lists):
for b in list_of_lists[i+1:]:
if number_of_matches(a, b) >= target_num_words:
for g in groups:
if a in g or b in g:
g.append(a if b in g else b)
break
else:
groups.append([a, b])
merged = []
for g in groups:
if len(g) >= target_num_lists:
merged.append({x for l in g for x in l})
return merged
number_of_matches
基本上是您的 Levenshtein 代码,只是 returns 两个列表之间的匹配词数。即使这不是您想要的,这也应该让您了解如何实现。
这个答案有两种解法。对于两者,您需要创建一个列表,其中包含您要比较的所有列表。
例如,使用上面的案例,您将执行以下操作:
lists = [first_list, second_list]
ITERTOOLS 解决方案
在此解决方案中,您使用 itertools.combinations
方法遍历所有可能的组合,这意味着它将每个列表与其他所有列表进行比较。你会像这样实现它:
import itertools
for a, b in itertools.combinations(lists, 2):
for first in a:
for second in b:
if levenshtein(first, second) < 2:
merged.append(first)
itertools.combinations
方法有两个参数,第一个是可迭代对象,第二个是每个组合中元素的数量。本例2. 例如:
itertools.combinations('ABCD', 2)
returns:
('A', 'B')
('A', 'C')
('A', 'D')
('B', 'C')
('B', 'D')
('C', 'D')
和:
itertools.combinations('ABCD', 3)
returns:
('A', 'B', 'C')
('A', 'B', 'D')
('A', 'C', 'D')
('B', 'C', 'D')
FOR循环解决方案
如果您不想导入一些奇怪的模块,请不要担心。您始终可以使用此解决方案,它只需要 2 for
个循环。
for i in range(len(lists)):
for j in range(i + 1, len(lists)):
for first in lists[i]:
for second in lists[j]:
if levenshtein(first, second) < 2:
merged.append(set([first,second]))
通过这样做,您可以成功地将每个列表中的每个项目与其他列表中的每个项目进行比较,而无需将 2 个列表进行两次比较。
我写了一个 Python 函数,它接受两个列表,使用 Levenshtein 比较它们并将足够相似的单词合并到一个名为“merged”的列表中。
如何为 6 个以上的列表执行此操作?确保将每个列表与其他 5 个列表进行比较等等?
first_list = ["Mouse", "Cat", "Dog", "Gremlinge", "Horse"]
second_list = ["Mouse", "Cat", "Hors", "Dog", "Gremling"]
third_list = ["Mouse", "Cat", "Horrs", "Dog", "Greemling"]
fourth_list = ["Mouse", "Cate", "Dog", "Gremlinge", "Horse"]
fifth_list = ["Mose", "Cat", "Hors", "Dog", "Gremling"]
sixth_list = ["Mouse", "Cat", "Horser", "Doeg", "Gremling"]
def lev_merging(a, b): # function to compare 2 lists
merged = [] # Empty list to add the matching words
for first in a:
for second in b:
if levenshtein(first, second) < 2:
merged.append(set([first,second]))
return merged
print (lev_merging(first_list,second_list))
我们将得到一个字符串列表列表
list_of_lists = [["Mouse", "Cat", "Dog", "Gremlinge", "Horse"],
["Mouse", "Cat", "Hors", "Dog", "Gremling"],
["Mouse", "Cat", "Horrs", "Dog", "Greemling"],
["Mouse", "Cate", "Dog", "Gremlinge", "Horse"],
["Mose", "Cat", "Hors", "Dog", "Gremling"],
["Mouse", "Cat", "Horser", "Doeg", "Gremling"]]
然后我们将遍历此列表,跟踪我们所在列表的索引 "in",并将此列表与它之后的所有列表进行比较。
def merging(list_of_lists):
merged = []
for i, a in enumerate(list_of_lists):
for b in list_of_lists[i+1:]:
for first in a:
for second in b:
if lev(first, second) < 2:
merged.append((first, second))
return merged
编辑:下面的代码将成对的列表传递给一个函数,并将它们分成几组。然后我们将把这些组中的每一个处理成集合,以删除重复项。
target_num_words = 6
target_num_words
def merging(list_of_lists):
groups = []
for i, a in enumerate(list_of_lists):
for b in list_of_lists[i+1:]:
if number_of_matches(a, b) >= target_num_words:
for g in groups:
if a in g or b in g:
g.append(a if b in g else b)
break
else:
groups.append([a, b])
merged = []
for g in groups:
if len(g) >= target_num_lists:
merged.append({x for l in g for x in l})
return merged
number_of_matches
基本上是您的 Levenshtein 代码,只是 returns 两个列表之间的匹配词数。即使这不是您想要的,这也应该让您了解如何实现。
这个答案有两种解法。对于两者,您需要创建一个列表,其中包含您要比较的所有列表。
例如,使用上面的案例,您将执行以下操作:
lists = [first_list, second_list]
ITERTOOLS 解决方案
在此解决方案中,您使用 itertools.combinations
方法遍历所有可能的组合,这意味着它将每个列表与其他所有列表进行比较。你会像这样实现它:
import itertools
for a, b in itertools.combinations(lists, 2):
for first in a:
for second in b:
if levenshtein(first, second) < 2:
merged.append(first)
itertools.combinations
方法有两个参数,第一个是可迭代对象,第二个是每个组合中元素的数量。本例2. 例如:
itertools.combinations('ABCD', 2)
returns:
('A', 'B')
('A', 'C')
('A', 'D')
('B', 'C')
('B', 'D')
('C', 'D')
和:
itertools.combinations('ABCD', 3)
returns:
('A', 'B', 'C')
('A', 'B', 'D')
('A', 'C', 'D')
('B', 'C', 'D')
FOR循环解决方案
如果您不想导入一些奇怪的模块,请不要担心。您始终可以使用此解决方案,它只需要 2 for
个循环。
for i in range(len(lists)):
for j in range(i + 1, len(lists)):
for first in lists[i]:
for second in lists[j]:
if levenshtein(first, second) < 2:
merged.append(set([first,second]))
通过这样做,您可以成功地将每个列表中的每个项目与其他列表中的每个项目进行比较,而无需将 2 个列表进行两次比较。