How to use a Boolean to exit out of a 'for' loop?

Viewed 360

I am a beginner in Python, so I apologise in advance if my question is very basic or obvious. I am trying to write a function called find(my_list, value) that takes a list, and a value as parameters. The function searches for the value in the list and returns the index at which the first occurrence of the value is found in the list. I want the function to return -1 if the value isn't found in the list.

The catch is that I am unable to use any in-built functions, except for range() and str(). I also cannot use quit() or exit() or break or return statements to exit out of loops.

I am attempting to use a 'for' loop method, as well as a Boolean statement (to control when to stop the loop). I think I am on the right track, but believe there is an issue with my implementation. I am getting the desired output (-1) for when the value is not in the list. But, I cannot seem to get the desired output for when the value is in the list. Any guidance would be appreciated.

    def find(my_list, value):

        index = 0
        valid = False

        if value != my_list:
            found = -1

        for element in my_list:
            if element == value:
                valid = True
                found = index

        else: 
            index += 1

    return found

The list:

    str_list1 = ['r', 'i', 'n', 'g', 'i', 'n', 'g']

The call to the function:

    print(list_function.find(str_list1, 'g'))
    print(list_function.find(str_list1, 'z'))

Expected output:

    3
    -1
4 Answers

Your indentation is off. You intended the else go belong to the if statement, but it's actually bound to the for loop, which means index is only increment when the loop exits naturally (which is always, because you don't have any other way of exiting the loop (a break statement or a return statement).

def find(my_list, value):
    index = 0
    for element in my_list:
        if element == value:
            return index
        else:
            index += 1

    # If we get here, no match was found
    return -1

Note that we don't need valid.

A cleaner way to write this is to use enumerate, which generates the index for you.

def find(my_list, value):
    for index, element in enumerate(my_list):
        if element == value:
            return index

    # If we get here, no match was found
    return -1

Update: If you can't break out of the loop early, you do need valid, though you still need to keep the index to return separate from the current index. (I'm guessing you can't use enumerate either.)

def find(my_list, value):
    answer = -1
    index = 0
    for element in my_list:
        if element == value:
            answer = index
        index += 1
    
    return answer

This will return the index of the last value found, if value appears more than once. To return the first instance, you'll want to check if answer has already been changed from the default of -1.

def find(my_list, value):
    answer = -1
    index = 0
    for element my_list:
        if answer == -1 and element == value:
            answer = index
        index += 1
    
    return answer

    

I have kept the requirements of not using built-in functions and not using break.

Edit: I just read the post again, that you cannot cannot use return statements to exit out of loops, so here's another way to do it. I first assumed that the element is not found (-1), then loop through the list while increasing the index, and assign the index if the element is found. Here's the code:

def find(my_list, value):
    found = -1
    idx = 0

    for element in my_list:
        if (element == value) and (found == -1) :
            found = idx
        idx += 1

    return found

str_list1 = ['r', 'i', 'n', 'g', 'i', 'n', 'g']
print(find(str_list1, 'g'))
print(find(str_list1, 'z'))

Output:

3
-1

And if you can accept the use of .index() here's a sweet one

def find(my_list, value):
    return my_list.index(value) if value in my_list else -1

If you cannot use break, use while for a manual for loop.

First let's make if into a correct for loop with index:

        for index in range(len(my_list)):
            element = my_list[index]
            if element == value:
                valid = True
                found = index
                break # I know, it's only for now

Now we will go through it manually:

        while index < len(my_list):
            element = my_list[index]
            if element == value:
                valid = True
                found = index
                break
            index += 1

Now let's think: how else can we finish the while loop? By having a condition that is false!

Let's move the if condition to while condition but swapped (we want it to continue while not equal):

        while index < len(my_list) and my_list[index] != value:
            index += 1

Now, if index == len(my_list), then the element was not found (first part of the condition failed). If it's anything lower, then it's the found index. :)

        while index < len(my_list) and my_list[index] != value:
            index += 1
        return index if index < len(my_list) else -1

Edit: Now I see I shortened it quite a bit... To keep more of your code, you can do the and not valid as condition and that's probably what you planned from the start!

        while index < len(my_list) and not valid:
            element = my_list[index]
            if element == value:
                valid = True
            index += 1
        return index if valid else -1

You can use break to exit the loop:

def find(my_list, value):
    index = 0
    found = -1
    for element in my_list:
        if element == value:
            found = index
            break
        index += 1

return found

Instead of counting the index by hand, use enumerate:

def find(list, value):
    found = -1
    for index, element in enumerate(list):
        if element == value:
            found = index
            break
return found

You could use return directly inside to loop:

def find(list, value):
    for index, element in enumerate(list):
        if element == value:
            return index
return -1

or set index in a else-Block to for:

def find(list, value):
    for index, element in enumerate(list):
        if element == value:
            break
    else:
        index = -1
return index
Related