【问题标题】:comparing python dictionary values比较python字典值
【发布时间】:2015-12-02 06:39:59
【问题描述】:

我正在用 python 创建一个非常基本的搜索引擎,我正在创建一种处理短语查询的方法,所以如果 2 个单词的位置在 1 以内,它们在文档中彼此相邻,它将输出发生这种情况的所有文档编号。

我目前有一本像这样的字典

{'8':[['1170', '1264', '1307', '1559', '1638'], ['197', '1169']], 
 '6':[['345', '772'], ['346']}

这只是一个布局示例。

w=word, p=position ||
{doc1:[w1p1, w1p2, w1p3],[w2p1, w2p2]}

key 是文档 id,然后是文档中第一个单词包含的位置,然后是第二个单词的位置。将有与查询中的一样多的单词(位置分组)。

我的问题是,有没有一种方法可以比较相同文档 ID 的 1 和 2nd + 3rd 等的值?我想比较它们,看看一个词的位置是否只是另一个词的+1。

所以你可以看到 doc 6 单词 2 跟在单词 1 之后,这将导致密钥被发回。

【问题讨论】:

    标签: python dictionary


    【解决方案1】:

    有几种方法可以实现您在此处尝试执行的操作。根据您给我的示例,我假设始终只有两个单词,并且列表始终按顺序排列。

    无论使用什么方法,您都需要遍历文档(字典)。在 Python 中迭代字典很简单;你可以看到一个例子here。之后,步骤改变

    第一个选项 - 效率较低,稍微简单一些:

    1. 遍历列表 1 中的每个项目(位置)(第一个单词的位置)。
    2. 遍历列表 2 中的每个项目(位置)(第二个单词的位置)。
    3. 比较两个位置,如果它们在 1 以内,则返回文档 id。

      例子:

      for documentNumber in docdictionary:
          for word1location in docdictionary[documentNumber][0]:
              for word2location in docdictionary[documentNumber][1]:
                  if abs(word1location - word2location) == 1:
                      return documentNumber
      

    第二个选项 - 更高效,稍微复杂一点:

    1. 从每个单词位置列表的开头开始,跟踪您的位置
    2. 检查您所在位置的两个值。
      • 如果两个值相差 1 个字,则返回文档编号
      • 如果两个值都不是,请检查哪个列表项(页面位置)具有较低的值并移至该列表中的下一项,重复
    3. 如果其中一个列表(例如列表 1)用完数字,而另一个列表(列表 2)的值大于第一个列表(列表 1)的最后一个值,则返回 None。

      例子:

      for documentNumber in docdictionary:
          list1pos = 0
          list2pos = 0
          while True:
              difference = docdictionary[documentNumber][0][list1pos] - docdictionary[documentNumber][1][list2pos]
              if abs(difference) == 1:
                  return documentNumber
              if difference < 0: #Page location 2 is greater
                  list1pos++
                  if list1pos == len(docdictionary[documentNumber][0]): #We were at the end of list 1, there will be no more matches
                      break
              else: #Page location 1 is greater
                  list2pos++
                  if list2pos == len(docdictionary[documentNumber][1]): #We were at the end of list 2, there will be no more matches
                      break
      return None
      

    提醒一下,选项 2仅在列表始终排序时有效。此外,您并不总是需要立即返回文档 ID。如果您想要该对出现的所有文档而不是它找到的第一个文档,您可以将文档 ID 添加到列表中。您甚至可以使用字典轻松跟踪单词对在每个文档中出现的次数。

    希望这有帮助!如果有任何不清楚的地方,请告诉我。

    【讨论】:

    • 字数可以增加,因为它是查询中的字数。
    • @simitar 答案的第二部分实现了“mergesort”的“merge”部分,它可以推广到任意数量的列表。
    • @BiRico ,我将如何执行此操作,因为我需要比较 1 和 2 的位置,然后比较 2 和 3 的位置,依此类推,以查询查询中的尽可能多的单词.
    • @simitar 我不太明白你的问题。您的问题是“how can I merge k sorted lists”还是“mergesort 与我的问题有什么关系”或其他问题?
    • @simitar 这里的关键是要理解,在合并排序中,必须比较所有连续的项目,以便如果输入看起来像这样:[[..., 8, ...], [..., 9, ...], [..., 10, ...]],输出必须看起来像这样[..., 8, 9, 10, ...]。您不会创建输出,但您确实希望完成比较组合输入中所有连续项目的过程。那有意义吗?实际上,您的问题可能会简化一点,因为您似乎只需要比较 1 & 2、2 & 3、3 & 4 等连续项目。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多