【问题标题】:Python Loop Iteration issuePython循环迭代问题
【发布时间】:2017-01-08 05:29:29
【问题描述】:

两个版本,返回相反的答案,但总是一个错误。我不确定我哪里出错了。我尝试了一系列其他选项,但这似乎是最接近的。 编辑:需要循环

目标:识别列表中的元素,识别何时不在列表中,识别列表何时为[],相应地返回字符串。

def search_for_string(a_list, search_term):
    i=0
    for search_term in a_list:
        i += 1
        if a_list[i] == search_term: 
            return 'string found!' 
        elif a_list[i] != search_term:
            return 'string not found2'
    if len(a_list) == 0:
        return 'string not found'

apple = search_for_string(['a', 'b', 'c'], 'd')
print(apple)


def search_for_string(a_list, search_term):
    i=0
    for search_term in a_list:
        if a_list[i] == search_term: 
            return 'string found!' 
        elif a_list[i] != search_term:
            return 'string not found2'
        i += 1
    if len(a_list) == 0:
        return 'string not found'

apple = search_for_string(['a', 'b', 'c'], 'd')
print(apple)

其他测试:

apple = search_for_string(['a', 'b', 'c'], 'b')
apple = search_for_string([], 'b')

【问题讨论】:

  • 首先,您将覆盖变量 search_term 的值。例如,您将其作为“d”传递,但由于您的 for 循环使用相同的变量名,它将被覆盖。要查看发生了什么,请尝试在 for 循环中打印 search_term 的值。 (即在 for 循环的第一行下方添加 print(search_term) 作为一行。)这可以帮助您调试。
  • 我明白你的意思,但我不知道该怎么办哈哈我会继续胡闹
  • 您可能需要查找 enumerate(). 它会为您保存 i 对象。
  • 谢谢!是的,我已经检查过了(重新开始并为这个问题找到解决方案哈哈)。看起来确实很有帮助。
  • 您能否回顾一下您的所有帖子,并在适当的地方选择答案,并为您选择的答案以及您认为值得的任何其他答案投票,尽管不是您最终选择的答案。我的意思不是听起来粗鲁,所以如果遇到这种情况,我深表歉意,但这是 Stack Exhange 及其网络如何运作的一个非常重要的部分(免责声明 - 我给出了一个选定的答案,但没有得到我预期的支持其中,所以我可能有点偏见和脾气暴躁...... ;) )。 Stephan Rauch 在下面给出了一个很好的答案。

标签: python loops iteration


【解决方案1】:

Python 让你的生活变得超级轻松:

def search_for_string(a_list, search_term):
    if search_term in a_list:
        return 'string found!'
    return 'string not found'

【讨论】:

    【解决方案2】:

    您的代码中几乎没有错误和非 Pythonic:

    def search_for_string2(a_list, search_term):
        i=0  # <----- Not Pythonic! If you want to get index we use enumerate(a_list)
        for search_term in a_list: # <--- search_term passed to function is lost and gets overwritten by elements in a_list.
            i += 1 # <--- Not Pythonic in this context
            if a_list[i] == search_term: #<--- a_list[index+1] == a_list[index]. True if consecutive elements are same else False!
                return 'string found!' #<--- No WRONG!, You didn't find the string, Consecutive elements are same!
            elif a_list[i] != search_term:
                return 'string not found2' #<-- Consecutive elements are not same!
        if len(a_list) == 0:
            return 'string not found'
    

    根据您定义的目标,您可以像这样实现它:

    def search_for_string(alist, search_term):
        if not alist:
            return "List is empty"
        if search_term in alist:
            return "First occurence of string Found at index position: " + str(alist.index(search_term))
        else:
            return "String not found"
    
    
    print(search_for_string(['a', 'b', 'c'], 'd'))
    print(search_for_string(['a', 'b', 'c'], 'b'))
    print(search_for_string([], 'b'))
    

    输出:

    String not found
    First occurence of string Found at index position: 1
    List is empty
    

    【讨论】:

      【解决方案3】:

      简短的回答是,!= 的返回并没有按照您的想法执行,并且列表是 0 索引而不是 1 索引。代码实际上比你想象的要简单得多:

      def search_for_string(haystack, needle):
          if not haystack: # check for empty list
              return 'List was empty!'
          for x in haystack:
              if needle == x:
                  return 'String found!'
          return 'String not found!'
      

      本质上,只有在您至少检查过每个元素一次后,您才知道是否找不到字符串。但是你知道是否找到了一个字符串,好吧,当你找到它时。


      现在解释一下您的代码存在的问题:

      1. 此版本不起作用,因为 (1) 它跳过了列表中的第一个元素,并且 (2) 它仅在检查第一个元素后才返回未找到/找到的字符串:

        def search_for_string(a_list, search_term):
            i=0
            for search_term in a_list:
                i += 1
                if a_list[i] == search_term: # whoops this comparison checks for succeeding elements!
                    return 'string found!' 
                elif a_list[i] != search_term: # whoops this part returns  even before all succeeding elements are checked.
                    return 'string not found2'
            if len(a_list) == 0:
                return 'string not found'
        
        apple = search_for_string(['a', 'b', 'c'], 'd')
        # In the list ['a', 'b', 'c']
        # element [0] = 'a'
        # element [1] = 'b'
        # element [2] = 'c'
        print(apple)
        

      为了进一步解释,让我们逐步了解您的代码:

      # search_term == 'd'
      # a_list = [ 'a', 'b', 'c' ]
      i = 0 # at this point i == 0
      for search_term in a_list:  
          # Oh no!  we lost the search term that we passed into the 
          # function because we are using it as the loop iterator
          # search_term == 'a'
          i += 1 # i == 1
          if a_list[i] == search_term: 
              # checks to see if 'b' == 'a'
              return 'string found!'
          elif a_list[i] != search_term:
              # checks to see if 'b' != 'a'
              return 'string not found!' 
              # and we return after one iteration of the loop.
      

      你的第二个版本有同样的问题 (1)(2),但是避免了第一个元素没有被检查的问题。

      【讨论】:

      • if needle == haystack --> if needle == x?
      • 感谢您收听。
      • 是的,这行得通。抱歉忘了提到尝试在循环中执行此操作。
      • 我的理解是设置 i=0 从零开始迭代,并且 i+=1 每次循环时加一(因此将元素移动到元素)
      • 确实如此,但是由于您是在循环的顶部执行此操作,因此正如@mygz 所指出的那样,比较错误的事情是因为您使用search_term 作为循环迭代器。此外,由于您是在循环的顶部执行此操作,因此如果您的意图是将传入的 search_term 与特定列表元素进行比较,则您将跳过检查元素 #0。
      【解决方案4】:

      你的 search_for_string 函数有很多问题。

      主要问题是您正在覆盖变量search_term 的值。还有其他问题导致输出不正确。

      这是您的函数的更简单版本,它满足您的所有要求。

      def search_for_string(a_list, search_item):
        if(len(a_list) == 0):
             return 'List is empty'
        else:
          for search_term in a_list:
              if search_term == search_item: 
                  return 'string found!' 
          return 'string not found'
      

      【讨论】:

        【解决方案5】:

        您的代码中有很多错误。有些很重要,有些则不重要。我会尝试解决它们:

        • 您收到变量 search_term 作为函数参数,但随后您通过在 for 循环中使用它来覆盖它的值。
        • 您正在按值迭代a_list,但随后您尝试使用循环变量i 按索引进行迭代。不要这样做。您已经在按值进行迭代,无需同时进行。
        • 您正在尝试测试a_list 在您的函数的end 是否为空。一开始就做。更好的是,放弃 if 语句并在函数结束时简单地返回。如果a_list 为空,则不会运行 for 循环。

        现在,我将如何重写您的函数:

        >>> def search_for_string(lst, key):
            # only iterate by value.
                for string in lst:
                    # we only need to test once
                    # if `key` is equal to the
                    # current string we are on.
                    if string == key:
                        return 'string found'
                # no need to test if the list
                # is empty. The for loop will
                # never be run if it is, and
                # this return statement will
                # execute.
                return 'string not found'
        
        >>> search_for_string(['a', 'b', 'c'], 'd')
        'string not found'
        >>> search_for_string(['a', 'b', 'c'], 'b')
        'string found'
        >>> search_for_string([], 'b')
        'string not found'
        >>> 
        

        【讨论】:

          【解决方案6】:

          对于您的代码,您应该注意您没有正确搜索。您传入了 search_term,但 for x in y 中的变量将 x 设置为等于 y 中下一项的值。所以如果你有for x in [1, 2, 3],它第一次运行时会设置x = 1,等等。所以第一个函数将检查'a' =='b',它不是,第二个函数将检查'a ' == 'a',它就是——但也不是你要找的东西!

          查找项目是否在列表中的最佳方法是

          x in list
          

          如果 x 在列表中,这将返回 True 或 False! (但不要使用变量 'list',这是不好的做法,因为它会影响内置函数)。

          因此,一种更 Pythonic 的方式是

          def search_for_string(a_list, search_term):
              if search_term in a_list:
                  return 'string found!'
              elif not a_list:  # realistically you'd put this before here but I'm trying to mirror your code--why might you put this earlier? Because it's less costly than searching a list.
                  return 'empty list!'
              else:
                  return 'string not found!'
          

          还要注意bool([]) 返回 False,这是我们检查列表是否为空的方式。

          按照您的方式,我们不需要使用索引值,但您必须做很多额外的、不必要的工作。

          def search_for_string(a_list, search_term):
              for index, item in enumerate(a_list):
                  if a_list[index] == search_term:
                      return 'string found!'
                      # what do you think the value of 'item' is here? it's equal to a_list[index]!
                  elif len(a_list) == 0:  # again, you'd put this earlier--why make your computer do the work? it doesn't have to. Also, you could just do elif not a_list
                      return 'string not found'
                  else: 
                      continue
              return 'string not found2'
          

          【讨论】:

            【解决方案7】:

            与您的代码相关的大多数问题都在此处之前的答案中介绍,@Stephen Rauch 给出的答案总结了解决您问题的最 Pythonic 方法。

            还有一件事让你的代码不能做你想做的事,即使所有其他的东西都是正确的。

            当您在函数中return 时,您实际上是在退出该函数。

            因此,实际上,使用您一直在尝试的 for 循环方法,您将只检查 a_list 中的第一个值,如果它符合您的搜索条件,则返回“找到”,如果第一个值符合您的搜索条件,然后退出您的函数。

            基本上,您永远不会检查超出第一个值。

            【讨论】:

              【解决方案8】:

              首先, 第一种方法和第二种方法的区别是在执行 if 语句之前和之后增加 i 。如果您首先增加 i,您的循环将找不到列表第一个元素的值。 您使用 i 作为增量,但在 python 中不是必需的。您可以通过使用该元素是否在列表中来查找。

              def search_for_string(a_list, search_term):
              
                  #if a_list is empty, return False
                  if len(a_list) == 0:
                        return False
                  #if search_term has an element in a_list return the string
                  if search_term in a_list:
                        return "string found"
              
                  return "string not found"
              

              【讨论】:

                猜你喜欢
                • 2016-01-14
                • 2015-02-16
                • 2020-05-26
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2012-06-27
                • 2023-03-05
                相关资源
                最近更新 更多