Python 嵌套列表长度不等的多元素相似度计算

Python 嵌套列表长度不等的多元素相似度计算,python,list,similarity,Python,List,Similarity,我有一个嵌套列表,每一个元素都有不同的长度: lst = [[a,bcbcbcbcbc],[e,bbccbbccb],[i,ccbbccbb],[o,cbbccbb]] 我的输出是具有以下外观的数据帧的csv: comparison similarity_score a:e *some score a:i *some score a:o *some score e:i *some

我有一个嵌套列表,每一个元素都有不同的长度:

lst = [[a,bcbcbcbcbc],[e,bbccbbccb],[i,ccbbccbb],[o,cbbccbb]]
我的输出是具有以下外观的数据帧的csv:

comparison     similarity_score
   a:e          *some score      
   a:i          *some score
   a:o          *some score
   e:i          *some score
   e:o          *some score
   i:o          *some score
我的代码:

similarity = []
for i in lst:
    name = i[0]
    string = i[1]
    score = 0.0
    length =(len(string))
    for i in range(length):
        if string[i]==string[i+1]:
            score += 1.0
    new_score = (100.0*score)/length
    name_seq = name[i] + ':' + name[i+1]
    similarity.append(name_seq,new_score)

similarity.pdDataFrame(similarity, columns = ['comparison' , 'similarity_score'])
similarity.to_csv('similarity_score.csv')
但我收到了一个错误:

    if codes[i]==codes[i+1]:
          IndexError: string index out of range

有什么建议吗?谢谢

根据Python的文档
range
通过示例执行以下操作:

>>>范围(10)
[0,1,2,3,4,5,6,7,8,9]

在代码中(假设变量名未更改):

换句话说,给定一个输入
bcb
,if语句将查看以下索引:

(0,1)
(1,2)

(2,3)
根据Python的文档
range
通过示例执行以下操作:

>>>范围(10)
[0,1,2,3,4,5,6,7,8,9]

在代码中(假设变量名未更改):

换句话说,给定一个输入
bcb
,if语句将查看以下索引:

(0,1)
(1,2)

(2,3)
我认为您最大的问题是,在顶层,您只是一次迭代一对
名称、字符串,而不是您希望在输出中看到的一对
名称、字符串(如成对名称
a:e
所示)

稍后您将尝试为
名称
字符串
值编制索引,但这样做并不能达到您的目的(将两个字符串相互比较以计算分数),因为您只访问同一字符串中的相邻字符。您得到的异常是因为
i+1
可能会超出字符串的末尾。由于将
i
用于内部循环中的索引和从外部循环中获取的项目(名称、字符串对),因此会出现进一步的混淆

要获得成对的对,我建议使用
itertools.compositions

import itertools

for [name1, string1], [name2, string2] in itertools.combinations(lst, 2):
现在,您可以在循环的其余部分使用两个名称和两个字符串变量

我不能完全确定我是否理解如何比较字符串以获得分数,因为它们彼此的长度不同。如果只想比较字符串的初始部分(并忽略较长字符串的尾随位),可以使用
zip
获取两个字符串之间的对应字符对。然后可以在生成器表达式中比较它们,并将
bool
结果相加(
True
是整数
1
的特殊版本,
False
0
的版本)。然后可以除以字符串长度中较小的一个(或者如果要惩罚长度差异,可以除以较大的一个):

还有一个更明显的问题,就是您使用两个参数调用
append
。如果您真的想追加一个2元组,则需要一组额外的括号:

similarity.append((name_seq, new_score))

我认为您最大的问题是,在顶层,您只需一次迭代一对
名称、字符串
对,而不是您希望在输出中看到的一对
名称、字符串
对(如成对名称
a:e
所示)

稍后您将尝试为
名称
字符串
值编制索引,但这样做并不能达到您的目的(将两个字符串相互比较以计算分数),因为您只访问同一字符串中的相邻字符。您得到的异常是因为
i+1
可能会超出字符串的末尾。由于将
i
用于内部循环中的索引和从外部循环中获取的项目(名称、字符串对),因此会出现进一步的混淆

要获得成对的对,我建议使用
itertools.compositions

import itertools

for [name1, string1], [name2, string2] in itertools.combinations(lst, 2):
现在,您可以在循环的其余部分使用两个名称和两个字符串变量

我不能完全确定我是否理解如何比较字符串以获得分数,因为它们彼此的长度不同。如果只想比较字符串的初始部分(并忽略较长字符串的尾随位),可以使用
zip
获取两个字符串之间的对应字符对。然后可以在生成器表达式中比较它们,并将
bool
结果相加(
True
是整数
1
的特殊版本,
False
0
的版本)。然后可以除以字符串长度中较小的一个(或者如果要惩罚长度差异,可以除以较大的一个):

还有一个更明显的问题,就是您使用两个参数调用
append
。如果您真的想追加一个2元组,则需要一组额外的括号:

similarity.append((name_seq, new_score))

numPlaces在哪里初始化?代码[i]==代码[i+1]不会出现在代码段中,除非您指的是字符串[i]==字符串[i+1]什么是
numPlaces
(可能应该是
length
)?为什么异常中的行与显示的代码中的任何行都不匹配?不管怎么说,我认为您对
I
感到困惑,因为您在不同的时间对两个不同的事物使用相同的变量名。如果
name
在您的列表中是
a
,那么您所做的
name[i+1]
就毫无意义了。@Blckknght感谢您的更正。我必须承认我对for循环中的I很困惑。numPlaces初始化在哪里?代码[i]==代码[i+1]不会出现在代码段中,除非您指的是字符串[i]==字符串[i+1]什么是
numPlaces
(可能应该是
length
)?为什么异常中的行与显示的代码中的任何行都不匹配?不管怎么说,我认为您对
I
感到困惑,因为您在不同的时间对两个不同的事物使用相同的变量名。如果
name
在您的列表中是
a
,那么您所做的
name[i+1]
就没有任何意义了。@Blckkng