noob2014
noob2014

Reputation: 89

Python while looping over list but not finding value

I have a while loop that is looping over a list trying to find the number 1. I have the code below and it loops over "almost" all the list but it does not find the index for value 1

numbers = [24, 10, 92, 28, 71, 1, 80, 70]
counter = 0
number_to_find = 1

def my_loop():
    global counter
    while counter > 6: #Also not sure while 7 doesn't work, says out of range?
        if numbers[counter] == number_to_find:
            print "Number found at position", counter 
    
    else:
        print "Counter not found in position" , counter
        counter = counter + 1
        my_loop()


print my_loop()

Upvotes: 1

Views: 103

Answers (6)

AChampion
AChampion

Reputation: 30268

So there are many ways to do this, iteratively and recursively but to take the OP's code as is and what I think they were attempting.

Note: it is generally considered bad practice to use global variables, you should pass the list of numbers and the number to find to the function.

Note: your while loop is effectively implementing a for loop - for counter in range(len(numbers)): would provide the same result

numbers = [24, 10, 92, 28, 71, 1, 80, 70]
number_to_find = 1

def my_loop():
    counter = 0
    while counter < len(numbers):
        if numbers[counter] == number_to_find:
            print "Number found at position", counter 
        else:
            print "Counter not found in position" , counter
        counter = counter + 1

my_loop()

Output:

Counter not found in position 0
Counter not found in position 1
Counter not found in position 2
Counter not found in position 3
Counter not found in position 4
Number found at position 5
Counter not found in position 6
Counter not found in position 7

Doing the same thing with a for loop:

for counter in range(len(numbers)):
    if numbers[counter] == number_to_find:
        print "Number found at position", counter 
    else:
        print "Counter not found in position" , counter

Would output the same.
However, perhaps a more idiomatic approach for Python would be to use enumerate:

for counter, number in enumerate(numbers):
    if number == number_to_find:
        print "Number found at position", counter 
    else:
        print "Counter not found in position" , counter

Upvotes: 2

dot.Py
dot.Py

Reputation: 5157

You can achieve what you're looking for using the following piece of code:

numbers = [24, 10, 92, 28, 71, 1, 80, 1, 70]
number_to_find = 1

for i,j in enumerate(numbers):
    if j == number_to_find:
        print i, "=>", j

# Output
>>> 5 => 1
>>> 7 => 1

If your numbers doesn't contains repeated numbers, you can use the following piece of code, as sugested by kojiro:

numbers = [24, 10, 92, 28, 71, 1, 80, 70]
number_to_find = 1

print numbers.index(number_to_find)

# Output
>>> 5

But if your code contains repeated chars, it'll show only the first ocurrence:

numbers = [24, 10, 92, 28, 71, 1, 80, 1, 70]
number_to_find = 1

print numbers.index(number_to_find)

# Output
>>> 5

Upvotes: 3

erip
erip

Reputation: 16935

while counter > 6:

If counter is greater than 6, it must be 7 or greater. If you're looping while counter > 7, you're indexing out of the range of the size of the list (which is indexed from 0 to 7).

global counter

Don't do this. You shouldn't use globals. There are good reasons

def my_loop(): ... my_loop()

You don't need recursion for this. This is quite simple with just a for loop (in fact, you can do it without that).

I'll post a few ways to solve this problem:

enumerate

def find_needle(needle, haystack):
    for idx, item in enumerate(haystack):
        if needle == item:
            return idx
    return None

index

 def find_needle(needle, haystack):
     return haystack.index(needle)

These two implementations don't do exactly the same thing - the first will return None if needle isn't found in haystack, where the second will throw a ValueError. I think the former is more forgiving, but it's up to you.

Upvotes: 2

glibdud
glibdud

Reputation: 7850

For starters, I think you mean for your else block to correspond to the if. Right now it's associated with the while. Indent the else so it's aligned with the if, and then indent the three lines after the else to align with the print after the if:

        if numbers[counter] == number_to_find:
            print "Number found at position", counter 
        else:
            print "Counter not found in position" , counter
            counter = counter + 1
            my_loop()

Once you fix that, your second problem will be that your program will exit immediately because your while condition evaluates to 0 > 6, which is false, so the if block will never even run. Minimally you'll want to change the > to <. At that point, your code will mostly work like you expect it to, but consider:

  1. The application will go into an infinite loop once it finds the value it's looking for.
  2. A for loop would be much nicer than a while with a counter.
  3. You should really avoid using global variables if at all possible (it's very possible here).

Upvotes: 0

Radu Ionescu
Radu Ionescu

Reputation: 3532

To find first occurence use numbers.index(x) where x is the number you are searching or for all of them indices = [idx for idx, number in enumerate(numbers) if elem_list == x]

Upvotes: 0

kojiro
kojiro

Reputation: 77137

This is a very confusing bit of code.

  1. You print the output, but the function does not return anything. (It also prints things, but it does not return anything.)
  2. The function has a while loop and also recurs upon itself. (There are some cases where this is appropriate, but this is not one of them.)
  3. counter is initially 0, but your first check is if counter > 6. 0 is not greater than six. (This is not technically wrong, but very confusing.)
  4. The value 1 is at index 5. Why are you looking for 6?
  5. Once you have reached the desired index, you do not terminate the loop.

Upvotes: 9

Related Questions