在Python3.6中使用列表理解来循环和比较两个句子的依赖性三元组时出现语法错误

2024-05-13 16:41:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下两句话:

  1. 我想回家。你知道吗
  2. 我想离开。你知道吗

我的目标是使用中建议的内核来量化两个句子之间的相似性 this paper。我提取每个句子的所有依赖性三元组。这是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(?),来做这个计算?你知道吗

Tags: ingo列表for关系simlike句子
2条回答

您似乎想要实现的是一个累积结果,但您不能这样做,因为表达式sim += theta没有返回一个独立的对象,将其视为最终列表结果的一项。相反,您可以将theta变量与计数器相乘,或者创建一个theta列表,然后使用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中的diffence between expressions and statements。你知道吗

至于你在如何计算((# of matching nodes) * (1 if the relationship doesn't match, 2.5 if it does))的评论中的问题,这是你问题中论文的^{相似函数的分子,你可以使用生成器和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)))

请注意,如果在deps1deps2中有许多元素,那么使用generator expression instead of a list comprehension可能更有效,因为每个迭代的单个结果不需要存储在内存中。你知道吗

相关问题 更多 >