【问题标题】:Inverted Index in Python not returning desired resultsPython中的倒排索引未返回所需的结果
【发布时间】:2013-07-09 17:52:57
【问题描述】:

我无法在 python 中为倒排索引返回正确的结果。我试图在变量“strlist”中加载一个字符串列表,然后用我的反向索引遍历字符串以返回它出现的单词+。到目前为止,这是我所做的:

def inverseIndex(strlist):
  d={}
  for x in range(len(strlist)):
    for y in strlist[x].split():
      for index, word in set(enumerate([y])):
        if word in d:
          d=d.update(index)
        else:
          d._setitem_(index,word)
        break
      break
    break
  return d

现在当我运行 inverseIndex(strlist)

它返回的只是{0:'This'},我想要的是一个字典,将'strlist'中的所有单词映射到集合d

我最初的方法是错误的吗?我在 if/else 中绊倒了吗?非常感谢任何和所有帮助。为我指明正确的方向。

【问题讨论】:

  • break 的缩进级别是否正确显示在这里?
  • 为什么你break在第一次迭代后退出所有循环?
  • 什么是d._setitem_
  • 如果您显示一些示例输入和所需的输出,也许会有所帮助。我不知道你想要完成什么。
  • 请忽略不赞成票 - 显然您在这里已经尽力了。反对票适用于那些不尝试并期望我们为他们完成家庭作业/工作的人。

标签: python indexing inverse


【解决方案1】:

根据你所说的,我认为你正在尝试获取一些这样的数据:

input = ["hello world", "foo bar", "red cat"]
data_wanted = {
    "foo" : 1,
    "hello" : 0,
    "cat" : 2,
    "world" : 0,
    "red" : 2
    "bar" : 1
}

所以你应该做的是将 words 作为键添加到字典中,并将它们的值作为它们所在的strlist 中的子字符串的索引。

def locateWords(strlist):
d = {}
for i, substr in enumerate(strlist):   # gives you the index and the item itself
    for word in substr.split()
        d[word] = i
return d

如果该词出现在strlist中的多个字符串中,则应将代码更改为:

def locateWords(strlist):
d = {}
for i, substr in enumerate(strlist):
    for word in substr.split()
        if word not in d:
            d[word] = [i]
        else:
            d[word].append(i)
return d

这会将值更改为列表,其中包含 strlist 中包含该单词的子字符串的索引。

解释了您的一些代码问题

  1. {} 不是集合,而是字典。
  2. break 强制循环立即终止 - 你不想提前结束循环,因为你还有数据要处理。
  3. d.update(index) 会给你一个TypeError: 'int' object is not iterable。这个方法实际上接受一个可迭代对象并用它更新字典。通常你会为此使用一个元组列表:[("foo",1), ("hello",0)]。它只是将数据添加到字典中。
  4. 您通常不想使用d.__setitem__(无论如何您都打错了)。你只需使用d[key] = value
  5. 您可以改用“for each”样式循环进行迭代,就像我上面的代码所示。循环范围意味着您正在循环索引。 (不完全是问题,但如果您不小心正确使用索引,可能会导致额外的错误)。

看起来你来自另一种编程语言,其中大括号表示集合,并且有一个结束控制块的关键字(如if, fi)。刚开始时很容易混淆语法 - 但如果您在运行代码时遇到问题,请查看您获得的异常并在网络上搜索它们!

P.S.我不知道你为什么想要一个集合 - 如果有重复,你可能想知道它们的所有位置,而不仅仅是第一个或最后一个或介于两者之间的任何位置。只是我的 0.02 美元。

【讨论】:

  • 哇,非常感谢您的分解。你猜对了,我也在尝试获取重复的位置。我一路迷路,只是想从代码中得到某种结果来帮助我指明正确的方向。
  • 我正在重新阅读您提供的代码,非常清晰,谢谢您的帮助。
【解决方案2】:

break 不是块结束标记;它的意思是“如果你点击这行代码,立即退出循环”。您可能不想要所有这些 break 语句。

我不确定您认为update 方法的作用。

d.update(index)

将尝试将index 视为dict 或键值对序列,并将index 中的所有映射添加到d。由于index 是一个数字,这似乎不是您期望update 做的事情。此外,update 返回 None,这相当于 Python 不返回任何内容,因此您可能不想将其值分配给 d

我不确定你期望什么

for index, word in set(enumerate([y])):

要做。让我们回顾一下它的作用。 [y] 创建一个 1 元素列表,其唯一元素是 y。然后enumerate([y]) 将返回一个迭代器,产生一个元素,元组(0, y)set(enumerate([y])) 然后将从该迭代器中获取所有项目(因此只有一个项目)并创建一个包含这些项目的集合。最后,for index, word in set(enumerate([y])): 将遍历该单项集,使用index == 0word == y 执行单个循环迭代。这可能不是您想要做的。

__setitem__ 特殊方法(每边有两个下划线)被 Python 调用来实现元素赋值。

d.__setitem__(index, word)

最好写成

d[index] = word

如果你想迭代strlist,那么你可以直接迭代strlist,而不是使用range(len(strlist))

  for x in range(len(strlist)):
    for y in strlist[x].split():

等价于

  for string in strlist:
    for y in string.split():

因为遍历 strlist 将给出 strlist 的项目。

希望对你有帮助。

【讨论】:

  • 感谢您的帮助,并解释了我的许多错误。进行此细分并查看我哪里出错以及如何做得更好会很有帮助。
猜你喜欢
  • 1970-01-01
  • 2014-10-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多