synset.hyperym_distances() 中是否有重复项?

Is there any duplicates in synset.hyperym_distances()?

我只是在查看函数 (hypernym_distances()),当我看到所有可能的上位词的结果时,有两个 "entity.n.01" 元素具有不同的距离,这是什么原因它 ?有人可以解释一下吗?

在Python中:

print([{i[0] : i[1]} for i in wn.synset('person.n.01').hypernym_distances()])

以上代码将显示导致最终术语 'entity' 的所有上位词。

输出为:

[{Synset('entity.n.01'): 3}, {Synset('object.n.01'): 4}, {Synset('physical_entity.n.01'): 5}, {Synset('organism.n.01'): 1}, {Synset('person.n.01'): 0}, {Synset('entity.n.01'): 6}, {Synset('living_thing.n.01'): 2}, {Synset('physical_entity.n.01'): 2}, {Synset('causal_agent.n.01'): 1}, {Synset('whole.n.02'): 3}]

这是一个包含同义词集的名称-值对,该同义词集是指定词的上位词之一。

谁能解释一下 'entity.n.01' 在输出中出现两次的原因。

{语法集('entity.n.01'): 6}

{语法集('entity.n.01'): 3}

当代码很迟钝时,分解它们。

此外,尽量不要使用单线,它们通常没有计算速度提升,只是你可以输入它们的速度。

了解您正在迭代的内容

所以让我们分解一下。

在为列表迭代的每个元素创建字典的列表理解的复杂打印中,我们看到:

print([{i[0] : i[1]} for i in wn.synset('person.n.01').hypernym_distances()])

看起来循环本身可以被简化。首先设置一个变量来保存同义词集。 (我假设您希望对多个同义词集执行相同的操作,而不是仅在 person.n.01 上使用它):

person = wn.synset('person.n.01')

现在让我们看看person.hypernym_distances() returns:

>>> person.hypernym_distances()
{(Synset('person.n.01'), 0), (Synset('organism.n.01'), 1), (Synset('whole.n.02'), 3), (Synset('physical_entity.n.01'), 5), (Synset('causal_agent.n.01'), 1), (Synset('entity.n.01'), 3), (Synset('living_thing.n.01'), 2), (Synset('physical_entity.n.01'), 2), (Synset('entity.n.01'), 6), (Synset('object.n.01'), 4)}

person.hypernym_distances()的数据结构已经是一组元组,第一个元素是上位词,第二个元素是距离。 Synset('entity.n.01') 应该只在 person.hypernym_distances() 中出现一次,因为它是 set 类型。

在循环中解包 tuples/iterables 的可迭代对象

遍历元组时,您可以轻松地"unpack"它(参见Unpacking a list / tuple of pairs into two lists / tuples and How can I iterate through two lists in parallel?

 >>> from nltk.corpus import wordnet as wn
>>> wn.synset('person.n.01')
Synset('person.n.01')
>>> person = wn.synset('person.n.01')
>>> person.hypernym_distances()
{(Synset('person.n.01'), 0), (Synset('organism.n.01'), 1), (Synset('whole.n.02'), 3), (Synset('physical_entity.n.01'), 5), (Synset('causal_agent.n.01'), 1), (Synset('entity.n.01'), 3), (Synset('living_thing.n.01'), 2), (Synset('physical_entity.n.01'), 2), (Synset('entity.n.01'), 6), (Synset('object.n.01'), 4)}
>>> for ss, count in person.hypernym_distances():
...     print (ss,'\t', count)
... 
Synset('person.n.01')    0
Synset('organism.n.01')      1
Synset('whole.n.02')     3
Synset('physical_entity.n.01')   5
Synset('causal_agent.n.01')      1
Synset('entity.n.01')    3
Synset('living_thing.n.01')      2
Synset('physical_entity.n.01')   2
Synset('entity.n.01')    6
Synset('object.n.01')    4

通过以上述方式遍历元组列表,您可以避免丑陋的 (i[0], i[1]) for i in iterable_of_tuples 语法。而是 (a,b) for a,b in iterable_of_tuples.

列表与字典理解

您似乎正试图将 person.hypernym_distances() 中的元组放入字典中,其中键是同义词集,值是计数。

我想当您在 list comprehensiondictionary comprehension 之间绊倒时,就会出现错误。不需要为 person.hypernym_distances() 中的每个元素创建新字典。相反,我认为字典理解就是你要找的,即:

>>> {ss:count for ss, count in person.hypernym_distances()}
{Synset('object.n.01'): 4, Synset('whole.n.02'): 3, Synset('living_thing.n.01'): 2, Synset('organism.n.01'): 1, Synset('entity.n.01'): 6, Synset('person.n.01'): 0, Synset('causal_agent.n.01'): 1, Synset('physical_entity.n.01'): 2}

将元组列表转换为字典

实际上,如果上面的字典是你想要的,给定一个元组的可迭代对象,每个元组有 2 个项目,则将可迭代对象转换为字典会自动将元组中的第一项设置为键,将第二项设置为值:

>>> dict(person.hypernym_distances())
{Synset('object.n.01'): 4, Synset('whole.n.02'): 3, Synset('living_thing.n.01'): 2, Synset('organism.n.01'): 1, Synset('entity.n.01'): 6, Synset('person.n.01'): 0, Synset('causal_agent.n.01'): 1, Synset('physical_entity.n.01'): 2}

另见

原生 python 中有高性能容器数据结构可以处理这些,它们也带有漂亮的功能。参见 https://docs.python.org/3/library/collections.html