首页 > 解决方案 > 在 Python 3.6 中使用列表推导来循环和比较两个句子的依赖三元组时出现语法错误

问题描述

我有以下两句话:

  1. 我想回家。
  2. 我想离开。

我的目标是使用本文建议的内核来量化两个句子之间的相似性 。我提取每个句子的所有依赖三元组。这些是 3 个项目元组,包含句子中单词之间的所有关系,看起来像(tail, relationship, head)

为了计算相似度,我需要遍历句子中每一个可能的三元组组合,并根据有多少节点匹配以及关系是否匹配,将特定数字添加到相似度分数中。

我尝试在 for 循环中使用列表推导,因为我认为它比另一个嵌套 for 循环更有效,但出现语法错误。这是我的代码:

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')]

问题:

  1. 使用列表理解执行此操作的正确语法是什么?
  2. 有没有更有效的方法,也许使用 numpy(?),来做这个计算?

标签: pythonperformancenumpynlplist-comprehension

解决方案


您似乎想要实现的是累积结果,但您不能那样做,因为表达式sim += theta没有返回一个独立的对象以被视为最终列表结果的一项。您可以做的是将theta变量与计数器相乘或创建thetas 列表,然后使用np.cumsum()or创建累积版本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]]

推荐阅读