在Python3.6中使用列表理解循环并比较两个句子的依赖项三元组时出现语法错误
我有以下两句话:在Python3.6中使用列表理解循环并比较两个句子的依赖项三元组时出现语法错误,python,performance,numpy,nlp,list-comprehension,Python,Performance,Numpy,Nlp,List Comprehension,我有以下两句话: 我想回家 我想离开 我的目标是使用中建议的内核量化两个句子之间的相似性 . 我提取每个句子的所有依赖性三元组。这是3项元组,包含句子中单词之间的所有关系,看起来像(尾部、关系、头部) 为了计算相似度,我需要遍历句子中所有可能的三元组组合,并根据节点匹配的数量和关系是否匹配,向相似度分数中添加一个特定的数字 我尝试在for循环中使用列表理解,因为我认为它比另一个嵌套的for循环更有效,但我得到了一个语法错误。这是我的密码: sim = 0 theta = 2.5 for d1
sim = 0
theta = 2.5
for d1 in deps1:
[sim += theta for d2 in deps2 if ((d1[0]==d2[0] or d1[2]==d2[2]) and d1[1]==d2[1])]
[sim += 1 for d2 in deps2 if ((d1[0]==d2[0] or d1[2]==d2[2]) and d1[1]!=d2[1])]
以下是打印时deps1和deps2的外观,以供参考:
[('I', 'nsubj', 'want'), ('want', 'ROOT', 'want'), ('to', 'aux', 'go'), ('go', 'xcomp', 'want'), ('home', 'advmod', 'go')]
[('I', 'nsubj', 'like'), ('would', 'aux', 'like'), ('like', 'ROOT', 'like'), ('to', 'aux', 'leave'), ('leave', 'xcomp', 'like')]
问题:
您似乎想要实现的是一个累积结果,但您不能这样做,因为表达式
sim+=theta
没有返回一个独立的对象,将其视为最终列表结果的一项。您可以做的是将theta
变量与计数器相乘,或者创建theta
s列表,然后使用np.cumsum()
或itertools.accumulate()
创建一个累积版本,除非您希望同时保留原始结果和累积结果,否则不推荐使用该方法
另外,您可以使用itertools.product
来创建所有三元组的组合,而不是使用两个循环,您可以使用itertools.count
作为计数器
In [36]: from itertools import product, count
In [37]: c = count(1)
In [38]: [2.5*next(c) for d1, d2 in product(deps1,deps2) if ((d1[0]==d2[0] or d1[2]==d2[2]) and d1[1]==d2[1])]
Out[38]: [2.5, 5.0]
要在一个列表中执行这两个条件,您可以执行以下操作:
[(d1[1]!=d2[1] or 2.5)*next(c) for d1, d2 in product(deps1,deps2) if d1[0]==d2[0] or d1[2]==d2[2]]
在Python中,可以在列表理解中使用表达式,但不能使用语句。您可能想看看Python中的 关于如何计算
(#匹配节点的数量)*(1如果关系不匹配,2.5如果匹配))
,这是你问题中论文的SABK相似性函数的分子,你可以使用生成器和sum
函数:
theta = 2.5
sim = sum((((d1[0] == d2[0]) + (d1[2] == d2[2])) * (theta if d1[1] == d2[1] else 1) for d1, d2 in product(deps1, deps2)))
或者,如果您希望为每个句子的相似性功能分离代码,从而提高代码的可读性:
def sim_per_sentence(d1, d2):
matching_nodes = (d1[0] == d2[0]) + (d2[0] == d2[0])
relation_sim = theta if d1[1] == d2[1] else 1
return matching_nodes * relation_sim
sim = sum((sim_per_sentence(d1, d2) for d1, d2 in product(deps1, deps2)))
请注意,如果在
deps1
和deps2
中有许多元素,则使用a可能更有效,因为每次迭代的单个结果不需要存储在内存中 用于元组之间的匹配关系!扩展它以计算(#个匹配节点)*(1个如果不匹配,2.5个如果匹配))的最佳方法是什么?节点是元组中的第一个和第三个元素,它们之间的关系是第二个。关于生成器,这是一个很好的观点,特别是因为我不需要操纵结果。谢谢