【问题标题】:linear searching with two letters python使用两个字母python进行线性搜索
【发布时间】:2021-01-10 02:17:59
【问题描述】:

我有这个程序,它应该返回(使用线性搜索)“语料库”中紧跟“最后一个”(包括重复项)的“语料库”中单个字符的所有实例的列表。字符的顺序应与它们在语料库中出现的顺序相同

例子:

    filter_possible_chars('lazy languid line', 'la')
        ['z', 'n']
        filter_possible_chars('pitter patter batton', 'tt')
        ['e', 'e', 'o']
filter_possible_chars('pitter pattor batt', 'tt')
    ['e', 'o']

但是我的程序在第二个示例中遇到了问题,在单词 batt 中的第三个 tt 之后,它之后没有任何内容,所以它显然不应该在列表中添加任何其他内容,但是我的 IndexError 列表索引超出范围?

这是函数:

def filter_possible_chars(corpus, last):

listo = []
last_list = []
final = []

for thing in corpus:
    listo.append(thing)
for last_word in last:
    last_list.append(last_word)
    
    
for index, letter in enumerate(listo):
    
    if letter == last_list[0]:
        if listo[index+1] == last_list[1]:
            final.append(listo[index+2])  
print(final)

【问题讨论】:

    标签: python linear-search


    【解决方案1】:

    您似乎已经发现了问题;您有时会尝试访问索引超过列表最大索引的列表元素:final.append(listo[index+2]) 或此处listo[index+1]

    您可以定义一个帮助方法,首先检查访问是否成功。

    def get(_list, index):
        if len(_list) >= index - 1:
            return _list[index]
    
    my_list = [1, 2, 3]
    idx = get(my_list, 2) # 3
    idx = get(my_list, 4) # None
    if idx is not None:
      # do stuff
    

    【讨论】:

      【解决方案2】:

      您遇到的问题是'tt' 在您的第三个字符串的末尾,因此在尝试查找之后的字母时,您会增加索引,但字符串已到达末尾,当尝试将索引加一,你最终会要求一个不存在的字符

      首先,如果您想让它在这种情况下返回字符串的第一个字符,请使用modulus 运算符将值减小到零(如果超过):

      def filter_possible_chars(corpus, last):
      
          listo = []
          last_list = []
          final = []
      
          for thing in corpus:
              listo.append(thing)
          for last_word in last:
              last_list.append(last_word)
      
      
          for index, letter in enumerate(listo):
      
              if letter == last_list[0]:
                  if listo[(index+1)%len(corpus)] == last_list[1]:
                      final.append(listo[(index+2)%len(corpus)])
          print(final)
      

      或者,如果你希望它在这种情况下返回 None,你可以添加一个 if 语句来检测它是否在它的限制,如果是,什么都不做,然后使用 @987654324 跳到函数的末尾@

      【讨论】:

      • 我认为在这里使用模运算符是不正确的,因为虽然它确实可以防止越界错误,但它现在可能导致误报。例如"abcdefg"[10%7] 有时会给您一个可能与您的查询相匹配的字母,而实际上它永远不会匹配您的查询。您需要检测和处理越界情况,而不是掩盖它。
      【解决方案3】:

      好吧,试试这个,它解决了索引问题:

      import re
      
      query_list = [
      ['lazy languid line', 'la'],
      ['pitter patter batton', 'tt'],
      ['pitter pattor batt', 'tt']
      ]
      
      
      def search(query):
          query_string = query[0]
          query_key = query[1]
          result = []
          for match in re.finditer(query_key, query_string):
              if match.span()[-1] < len(query_string):
                  result.append(query_string[match.span()[-1]])
              else:
                  result.append(None)
          return result
      
      for query in query_list:
          result = search(query)
          print (query)
          print (result)
      

      输出:

      ['lazy languid line', 'la']
      ['z', 'n']
      ['pitter patter batton', 'tt']
      ['e', 'e', 'o']
      ['pitter pattor batt', 'tt']
      ['e', 'o', None]
      

      【讨论】:

        【解决方案4】:

        它后面什么都没有,所以它显然不应该在列表中放任何东西

        当代码到达倒数第二个t时,如果条件为真,它会尝试获取listo[index+2],这没什么,所以它会引发 IndexError 告诉你我不知道你想让我得到什么。当涉及到最后一个t时,它再次发生,试图获取listo[index+1]

        您可以在倒数第三个字符处停止搜索:

        def filter_possible_chars(corpus, last):
            result = []
            for i in range(len(corpus)-2):
                if corpus[i:i+2] == last:
                    result.append(corpus[i+2])
            print(result)
        

        【讨论】:

          【解决方案5】:

          您可以使用列表推导来做到这一点。

          def filter_possible_chars(corpus, last):
              parts = [word.split(last) for word in corpus.split() if last in word]
              return [w[1][0] for w in parts if w[1]]
          
          print (filter_possible_chars('lazy languid line', 'la'))
          print (filter_possible_chars('pitter patter batton', 'tt'))
          print (filter_possible_chars('pitter pattor batt', 'tt'))
          print (filter_possible_chars('pitter pattor batt', 'it'))
          print (filter_possible_chars('pitter pattor batt', 'er'))
          print (filter_possible_chars('pitter pattor batt', 'ox'))
          

          您可以将这两行组合成一个长列表理解,如下所示:

          return [word.split(last)[1][0] for word in corpus.split() if last in word and word.split(last)[1]]
          

          让我解释一下代码:

          parts = [word.split(last) for word in corpus.split() if last in word]
          

          在这里,我尝试使用

          将语料库拆分为单个单词
          for word in corpus.split()
          

          之后,我正在检查last 是否在单个单词中

          如果子字符串last 存在,那么我将使用last 作为子字符串再次拆分单词。这将给出两组字符串。第一部分将是last 中子字符串之前的所有字符,第二部分将是last 中子字符串之后的所有字符。

          例如,lazy 将被拆分为 ['', 'zy'] 的子字符串 la。而pitter 将被拆分为['pi', 'er']tt

          获得此列表后,您需要从索引 1 中选择第一个字符。

          搜索la:

          lazy languid line 将导致[['', 'zy'], ['', 'nguid']]

          用于搜索“tt”:

          pitter patter batton 将导致[['pi', 'er'], ['pa', 'er'], ['ba', 'on']]

          用于搜索“tt”:

          pitter pattor batt 将导致[['pi', 'er'], ['pa', 'or'], ['ba', '']]

          用于搜索“er”:

          pitter pattor batt 将导致[]

          搜索“牛”:

          pitter pattor batt 将导致[]

          这告诉我们,只要索引 1 的值有一个字符串,我们就可以选择所有结果。

          所以下一个列表理解语句是:

          return [w[1][0] for w in parts if w[1]]
          

          在这里,我们从parts 中提取每个块,并检查索引 1 是否包含任何字符串。如果是,则提取第0个位置并返回。

          以下语句的输出是:

          print (filter_possible_chars('lazy languid line', 'la'))
          print (filter_possible_chars('pitter patter batton', 'tt'))
          print (filter_possible_chars('pitter pattor batt', 'tt'))
          print (filter_possible_chars('pitter pattor batt', 'it'))
          print (filter_possible_chars('pitter pattor batt', 'er'))
          print (filter_possible_chars('pitter pattor batt', 'ox'))
          
          ['z', 'n']
          ['e', 'e', 'o']
          ['e', 'o']
          ['t']
          []
          []
          

          【讨论】:

            猜你喜欢
            • 2017-12-16
            • 1970-01-01
            • 2019-04-09
            • 1970-01-01
            • 2014-05-29
            • 1970-01-01
            • 1970-01-01
            • 2013-10-16
            • 2017-09-04
            相关资源
            最近更新 更多