【问题标题】:Python: Split dictionary values into terms and make dictionary out of itPython:将字典值拆分为术语并从中制作字典
【发布时间】:2020-04-03 16:01:00
【问题描述】:

我有一个由数字组成的文件 - 文档 ID;和文本 - 文档:

1000 世界末日

1001 这很好

需要创建术语词典和帖子列表。 术语字典表示文档,只是分成术语并与文档 id 配对。术语字典应该是,我猜(key:term,value:document_id)像这样:

=1000

世界 = 1000

结束 = 1000

这 = 1001

是 = 1001

精细 = 1001

Postings 列表表示该术语所在的文档。应该如下所示:

这 = 1000 1001

= 1000 1001

第一个 = 1000

我只是通过将文档拆分为术语而成功(甚至不知道我是否做得对)。下一步该怎么做?

Python 代码

#Open and read documents file
docLine = codecs.open('sample.txt', 'r', 'utf8').read().splitlines()

#Empty dictionary
doc_dictionary = {}

#Split every line in id (keys) and documents (val) to save as dictionary
for document in docLine:
    (key, val) = re.split(r'\t+', document)
    doc_dictionary[key] = val
print("Documents")
print(doc_dictionary)

#Splits documents into words (terms)
print("") 
print("Words")
words = {key: [(val) for val in value.split()] for key, value in doc_dictionary.items()}
print(words)

结果

文档{

“1000”:“古腾堡计划的傲慢与偏见电子书,简·奥斯汀”,

'1001': '这本电子书可供任何人在任何地方免费使用,几乎没有任何限制。您可以根据本电子书随附的 Project Gutenberg 许可条款或在 www.gutenberg.org' 等网站上在线复制、赠送或重新使用它。

单词{

'1000': ['The', 'Project', 'Gutenberg', 'EBook', 'of', 'Pride', 'and', 'Prejudice', 'by', 'Jane', '奥斯汀'],

'1001': ['This', 'eBook', 'is', 'for', 'the', 'use', 'of', 'anyone', 'anywhere', 'at', 'no ', '成本', 'and', 'with', '几乎', 'no', 'restrictions', 'whatever.', 'You', 'may', 'copy', 'it,', 'give ', 'it', 'away', 'or', 're-use', 'it', 'under', 'the', 'terms', 'of', 'the', 'Project', 'Gutenberg ', '许可证', '包含', 'with', 'this', 'eBook', 'or', 'online', 'at', 'www.gutenberg.org'],

【问题讨论】:

    标签: python dictionary


    【解决方案1】:

    我会遍历你创建的字典:

    result = {}
    for key, list in words.items():
        for elem in list:
            if elem in result:
                if not key in result[elem]:
                    result[elem].append(key)
            else:
                result[elem] = [key]
    

    我试过了

    words = {'1000': ['the', 'world', 'the'],
             '1001': ['the', 'party']}
    

    结果:

    {'the': ['1000', '1001'], 'world': ['1000'], 'party': ['1001']}
    

    要在结果字典中搜索术语列表,您可以使用:

    for word in to_find:
        if word in result:
            print(word + ': ' + " ".join(result[word]))
        else:
            print(word + ': not found in dict')
    

    示例输入:to_find = ['the', 'party', 'car'] 给出以下输出:

    这个:1000 1001

    聚会:1001

    汽车:在字典中找不到

    【讨论】:

    • 感谢您的回答! Thats what I needed! Only problem is that ids 重复,因为在文件的某些行中有 2 个句子,这意味着术语也可能在该句子中。例如:1003 他是来聚会的。他走的路。 “他”:[1003 1003]。术语重复。
    • 谢谢!解决它!也许我可以问你最后一件事?如果我导入术语列表(正在导入要搜索的术语),如何在“结果”字典中搜索术语?
    • 如果我理解正确,请告诉我,我将编辑我的答案:您有一个要在结果字典中搜索的术语列表并获取它们出现的句子。这个对吗? @Morningshade
    • 是的!输出应该是:project = xxx1 xxx2 the = xxx1 xxx3
    • 是的,很酷,但请先公开提问,这样每个人都有机会回答!不客气,很高兴能帮到你!
    【解决方案2】:

    从您的问题看来,您似乎正在尝试交换新生成的dict 的键和值。这称为indexing,这是您在书后看到的内容以及搜索引擎如何快速提供结果。

    您可以通过以下方式在一次迭代中完成,而不是创建多个字典:

    from collections import defaultdict
    
    def normalize(line, pattern=re.compile(r"\W*\s+\W*")):
        # Use pattern to split line and trim non-word characters and set to lowercase
        return map(str.lower, pattern.split(line.strip(".!+,")))
    
    index = defaultdict(set)
    for document in docLine:
        key, value = re.split(r'\t+', document, 1)  # Split line into key and text parts
        for word in normalize(value):               # Normalize words to be used as index
            index[word].add(key)                    # Add key to word's set
    

    输出

    {'almost': {'1001'},
     'and': {'1001', '1000'},
     'anyone': {'1001'},
     'anywhere': {'1001'},
     'at': {'1001'},
     'austen': {'1000'},
     'away': {'1001'},
     'by': {'1000'},
     'copy': {'1001'},
     'cost': {'1001'},
     'ebook': {'1001', '1000'},
     'for': {'1001'},
     'give': {'1001'},
     'gutenberg': {'1001', '1000'},
     'included': {'1001'},
     'is': {'1001'},
     'it': {'1001'},
     'jane': {'1000'},
     'license': {'1001'},
     'may': {'1001'},
     'no': {'1001'},
     'of': {'1001', '1000'},
     'online': {'1001'},
     'or': {'1001'},
     'prejudice': {'1000'},
     'pride': {'1000'},
     'project': {'1001', '1000'},
     're-use': {'1001'},
     'restrictions': {'1001'},
     'terms': {'1001'},
     'the': {'1001', '1000'},
     'this': {'1001'},
     'under': {'1001'},
     'use': {'1001'},
     'whatsoever': {'1001'},
     'with': {'1001'},
     'www.gutenberg.org': {'1001'},     # Notice no trailing period.
     'you': {'1001'}}
    

    请查看我的Repl 完整示例。

    这利用了defaultdict,它确保每个新密钥都是特定类型(在本例中为set)。设置主字典。

    【讨论】:

    • 感谢您的回答!但现在我面临一个问题,我需要通过导入包含 5 个随机术语的文件来搜索术语。如何在集合中搜索?
    • @Morningshade 就像任何其他列表一样。如果你在一个集合中搜索一个项目,你可以使用in操作符例如if item in set_name,如果你正在搜索多个,那么将多个项目转换成一个集合,你可以使用set operations得到你的结果!
    • 好的。当我有空闲时间时,我会尝试:)
    猜你喜欢
    • 1970-01-01
    • 2022-01-15
    • 1970-01-01
    • 2021-09-09
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 2015-03-10
    相关资源
    最近更新 更多