在词典中用词汇收集引理

时间:2015-10-26 17:33:25

标签: python

我有一个格式为

的文本文件
word lemma
word lemma
word lemma    
像这样

workers  work
went     go
going    go
work     work
working  work

我要做的是用字词收集字典中的引理,所以输出会像这样

{work: workers, work, working}
{go: went, going}

我试过这个

mydict = {}
for line in myfile.splitlines():
    lemma = line.split()[1]
    word = line.split()[0]
    mydict[lemma] = word

但是这段代码给出了以下输出:

{'work': 'working', 'go': 'going'}

有人可以帮忙吗?

5 个答案:

答案 0 :(得分:3)

您的代码几乎是正确的!问题是mydict[lemma] = word覆盖word相关联的任何现有lemma。实际上,每个引理可以有多个与之关联的单词,因此我们真正想要做的是将新单词添加到集合中,而不是覆盖现有值。对此进行建模的自然方法是使用字符串的列表的字典,而不是字符串的字典。

mydict = {}
for line in myfile.splitlines():
    word, lemma = line.split()
    if lemma in mydict:
        mydict[lemma].append(word)
    else:
        mydict[lemma] = [word]

if声明是什么意思?如果lemma中的给定mydict已有条目,则我们将其添加到列表中。如果它还没有,我们用单例列表初始化该条目。

我也冒昧地使用Python的语法来解包序列。 word, lemma = line.split()相当于word = line.split()[0]; lemma = line.split()[1]

Python的一个好处是标准库可以满足许多简单的任务。这种用例正是标准库defaultdict的设计目标。使用下标运算符(defaultdict)索引dict[x]时,如果未找到任何值,则使用您提供的函数创建值。在这里,我们告诉defaultdict初始化一个新列表。

from collections import defaultdict
mydict = defaultdict(list)

现在代码更简单,因为defaultdict正在为我们检查if lemma in mydict。它总是会给我们一个(可能是空的)列表,我们可以在其中添加单词。

for line in myfile.splitlines():
    word, lemma = line.split()
    mydict[lemma].append(word)

在评论中,您建议您不要在输出中重复word个。标准库也可以在这里提供帮助。 set是一个有点像列表的数据结构,除了它不记得元素的顺序,它会自动删除重复项。 (在引擎盖下,它的作用类似于dict,只有键,没有值。)

我们只需要将defaultdict函数从list更改为set,并将append方法更改为适用于set s的版本(这被称为add。)

from collections import defaultdict
mydict = defaultdict(set)

for line in myfile.splitlines():
    word, lemma = line.split()
    mydict[lemma].add(word)

答案 1 :(得分:1)

正如我的评论建议的那样,您需要将列表作为您的值,而不仅仅是为每个键设置值。像这样的某些人应该工作。

mydict = {}
for line in myfile.splitlines():
    lemma = line.split()[1]
    word = line.split()[0]
    if lemma in mydict.keys():
        mydict[lemma].append(word)
    else:
        mydict[lemma] = [word]

答案 2 :(得分:1)

我建议使用defaultdict,使用list模块中的collections进行初始化。它符合这种情况,因为您可以轻松添加新元素并准备好list添加元素。

通过从集合中导入并提供defaultdict作为唯一参数,可以轻松地创建list

from collections import defaultdict

mydict = defaultdict(list)

然后,您可以根据append()的值来迭代文件中的每一行和word lemma

with open('lemmaaa', 'r') as myfile:
    for line in myfile:
        lemma = line.split()[1]
        word = line.split()[0]
        mydict[lemma].append(word)

使用您提供的输入,print(mydict)输出您正在寻找的地图:

defaultdict(<type 'list'>, {'go': ['went', 'going'], 'work': ['workers', 'work', 'working']})

答案 3 :(得分:0)

如果你对疯狂功能方法感兴趣,有一种“单一逻辑行”方式来完成它,这不涉及创建一个空字典并避免重复致电append

import itertools
import operator

with open('myfile.txt') as myfile:
    mydict = dict((k, [p[1] for p in grp]) 
         for k, grp in itertools.groupby(
             sorted(list(reversed(ln.split())) for ln in myfile),
             operator.itemgetter(0)))

说 取出文件的每一行,拆分,然后reverse sort这些行 group他们的元素[0]
通过获取反向分割线的[0],将元素[1]映射到组中的每个单词。

答案 4 :(得分:0)

import csv
import collections

with open('path/to/file') as infile:
    answer = collections.defaultdict(list)
    for word, lemma in csv.reader(infile, delimiter='\t'):
        answer[lemma].append(word)

如果你想在没有csv的任何帮助的情况下这样做:

answer = {}
with open('path/to/file') as infile:
    for line in infile:
        word, lemma = line.split()
        if lemma not in answer: answer[lemma] = []
        answer[lemma].append(word)