简体   繁体   English

Python循环迭代问题

[英]Python Loop Iteration issue

Two versions, return opposite answers, but always one comes out wrong. 两个版本,返回相反的答案,但总是一个出错。 I'm not sure where I've gone wrong. 我不确定我哪里出错了。 I've tried a series of other options, but this seems to get the closest. 我已经尝试了一系列其他选项,但这似乎是最接近的。 EDIT: Needs to be in a loop 编辑:需要循环

goals: identify element in list, identify when element is not in list, identify when list is [], return strings accordingly. 目标:识别列表中的元素,识别元素何时不在列表中,识别列表何时为[],相应地返回字符串。

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)

other tests: 其他测试:

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

Python makes your life super easy for this sort of thing: Python让你的生活变得非常容易:

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

There are few things wrong and Non-Pythonic in your code: 您的代码中存在一些错误和非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'

According to the goals you have defined you can implement it like so: 根据您定义的目标,您可以像这样实现它:

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'))

Output: 输出:

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

The short answer is that the return for != does not do what you think it does and that lists are 0-indexed not 1-indexed. 简短的回答是!=的返回不符合你的想法,而且列表是0索引而不是1索引。 The code is actually much simpler than you think: 代码实际上比你想象的要简单得多:

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!'

Essentially, you only know if a string was not found if you've gone through and checked each element at least once. 基本上,如果您已经完成并且至少检查过一次每个元素,您只知道是否找不到字符串。 But you know if a string was found, well, when you find it. 但是,当你找到它时,你知道是否找到了一个字符串。


Now to explain the issues with your code: 现在解释代码的问题:

  1. This version does not work because (1) it skips over the first element in the list and (2) it returns String not found/found only after checking the first element: 这个版本不起作用,因为(1)它跳过列表中的第一个元素,(2)它只在检查第一个元素后才返回String not found / found:

     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) 

To explain a little further let's take this step by step through your code: 为了进一步解释,让我们逐步完成您的代码:

# 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.

Your second version has the same problem (1)(2), but avoids the issue where the first element is not checked. 您的第二个版本具有相同的问题(1)(2),但避免了未检查第一个元素的问题。

There are lots of things wrong in your search_for_string function. 你的search_for_string函数有很多错误。

Main problem is that you're overwriting the value of the variable search_term . 主要问题是你要覆盖变量search_term的值。 There are other problems as well that are causing incorrect output. 还有其他问题导致输出错误。

Here's a simpler version of your function and it meets all your requirements. 这是一个更简单的功能版本,它符合您的所有要求。

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'

You have quite a few errors in your in code. 你的代码中有很多错误。 Some are important, others are not. 有些很重要,有些则不重要。 I'll try to address them: 我会尝试解决它们:

  • You're receiving the variable search_term as a function argument, but you then overwrite the value of it by using it in your for loop. 您正在接收变量search_term作为函数参数,但是您在for循环中使用它来覆盖它的值。
  • You're iterating over a_list by value, but you then attempt to use the loop variable i to iterate by index. 您按值迭代a_list ,但随后尝试使用循环变量i按索引进行迭代。 Don't do this. 不要这样做。 You're already iterating by value, you don't need to do both. 您已经按值迭代,您不需要同时执行这两项操作。
  • You're trying to test if a_list is empty at the end of your function. 您正试图在函数结束时测试a_list是否为空。 Do at the beginning. 在开始时做。 Better yet, ditch the if statement and simply return at the end of your function. 更好的是,抛弃if语句,只需在函数结束时返回。 The for loop will not be run if a_list is empty. 如果a_list为空,则不会运行for循环。

Now, here is how I'd rewrite your function: 现在,这是我如何重写你的功能:

>>> 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'
>>> 

For your code, you should note that you're not searching properly. 对于您的代码,您应该注意到您没有正确搜索。 You pass in search_term, but a variable in a for x in y sets x to be equal to the value of the next item in y. 您传入search_term,但是for x in y中的for x in y的变量将x设置为等于y中下一项的值。 So if you have for x in [1, 2, 3] , the first time it runs it will set x = 1, etc. So first function will check if 'a' == 'b', which it's not, and the second function will check if 'a' == 'a', which it is--but neither is what you're looking for! 因此,如果你for x in [1, 2, 3]for x in [1, 2, 3] ,它第一次运行时会设置x = 1,等等。所以第一个函数将检查'a'=='b',它不是,并且第二个函数将检查是'a'=='a',它是 - 但你不是要找的!

The best way to find if an item is in a list is 查找项目是否在列表中的最佳方法是

x in list

this will return True or False, if x is in the list or not! 如果x在列表中,则返回True或False! (don't use the variable 'list' though, it's bad practice since it shadows a built-in function). (不要使用变量'list',这是不好的做法,因为它会影响内置函数)。

So a more Pythonic way to do this would be 因此,更加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!'

Also note that bool([]) returns False, which is how we check if the list is empty. 另请注意, bool([])返回False,这是我们检查列表是否为空的方式。

To do it your way, we don't need to use index values, but you have to do a lot of extra, unnecessary work. 要按照自己的方式进行,我们不需要使用索引值,但是您必须做很多额外的,不必要的工作。

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'

Most of the issues relevant to your code are covered in previous answers here, and the answer given by @Stephen Rauch sums up the most Pythonic approach to your problem. 与您的代码相关的大多数问题在此处的答案中都有所涉及,@ Stete Rauch给出的答案总结了解决问题的最Pythonic方法。

There is one more thing that makes your code not do what you thing, even if all the other stuff was correct. 还有一件事使你的代码不能做你喜欢的事情,即使所有其他的东西都是正确的。

When you return in a function, you are effectively exiting that function. 当您return函数时,您实际上正在退出该函数。

So, effectively, using the for loop approach you've been trying, you would be only checking the first value in a_list, returning 'Found' if it met your search criteria, and returning 'Not found' if the first value did not match your search criteria, and then exiting your function. 所以,实际上,使用你一直在尝试的for循环方法,你只会检查a_list中的第一个值,如果它符合你的搜索条件则返回'Found',如果第一个值匹配则返回'Not found'您的搜索条件,然后退出您的功能。

Essentially, you'd never check beyond the first value. 从本质上讲,你永远不会超越第一个值。

First of all, difference in your first method and second method are incrementing i before and after your if statement is executed. 首先,第一种方法和第二种方法的区别在于在执行if语句之前和之后递增i。 If you increment i first, your loop won't find the value for the first element of the list. 如果先递增i,则循环将找不到列表第一个元素的值。 you are using i as an increment, but it is not necessary in python. 你使用i作为增量,但在python中没有必要。 You can just find out by using if the element is in a list. 您可以通过使用元素是否在列表中来找出。

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"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM