0

I am learning python and couldn't understand what is going on with flag in the below code snippet. Since I have updated the flag to false with in the if suite, I expect to see false printed from else, but the output shows true. Can someone please help me understand what is going on here.

objects=[1,2,3,4,5]
found_obj = None
for obj in objects:
    flag = True
    if obj == 3:
        found_obj = obj
        print("found the required object ",found_obj)
        flag= False

else:
    print ('Status flag ::', flag)

The below is the output I get when executing this code

found the required object  3
Status flag :: True
user2928913
  • 223
  • 1
  • 6
  • 15
  • 2
    You need to break from loop after find the number, also you have a bad indentation, the `else` must be in same indentation with `if` – Mazdak Jan 04 '15 at 16:31
  • @Kasra, I know what you mean, the loop runs the entire list even though it is not needed. But If I break from the loop, I will not enter the else. I really want to understand how I can access variable or objects in the else suite. – user2928913 Jan 04 '15 at 16:33
  • @Kasra: The indentation is fine (if this is intentional). The `else` block belongs to the `for` loop. It is run if the loop went through all the items without breaking out. – Jeff Mercado Jan 04 '15 at 16:34
  • @JeffMercado yes , in that case is true . – Mazdak Jan 04 '15 at 16:37
  • @user2928913 i dont get your mean by *access variable or objects in the else suite* , can you explain more ? – Mazdak Jan 04 '15 at 16:38
  • @user2928913 pls check out the Poke's answer ! i think its what you need to know ! – Mazdak Jan 04 '15 at 16:41
  • @All, My bad. Being an experiened java developer, I should have figured it out. But understood how stupid is my question. I was really focusing on accessing a variable created inside the for suite from with-in the else suite. Thanks everyone for answering the question. – user2928913 Jan 04 '15 at 16:49

3 Answers3

4

But If I break from the loop, I will not enter the else.

While that is true, there is no reason to actually have a for..else construct. Since you are searching for an element in a list, it makes sense that you break from the loop as early as possible. So you should just remove the else completely and run that print regardless of how the loop ended.

Furthermore, since you are trying to set your flag whether you have found the element or not, you should not reset it on every iteration:

found_obj = None
flag = True
for obj in objects:
    if obj == 3:
        found_obj = obj
        print("found the required object ",found_obj)
        flag = False
        break

print ('Status flag ::', flag)

Finally, since you are setting found_obj when you found an element, you don’t actually need that flag at all, since a value of None will tell you that you didn’t find anything, and any other value tells you that you did find it:

found_obj = None
for obj in objects:
    if obj == 3:
        found_obj = obj
        print("found the required object ",found_obj)
        break

print ('Status flag ::', found_obj is None)
poke
  • 369,085
  • 72
  • 557
  • 602
3

You set flag = True in the beginning of every iteration, thus it prints true where it is assigned to true in the last iteration where obj equals to 5

You might want to correct it by moving out flag = True from the for-loop:

flag = True
for obj in objects:
    if obj == 3:
        found_obj = obj
        print("found the required object ",found_obj)
        flag= False
        break  # no need to continue search
Paul Lo
  • 6,032
  • 6
  • 31
  • 36
0

If break-ing isn't an option, this is the fixed code:

objects=[1,2,3,4,5]
found_obj = None
flag = True # flag is set once, before the loop
for obj in objects:
    # this sets the flag to True *on each iteration*, we only want it once!
    # flag = True 
    if obj == 3:
        found_obj = obj
        print("found the required object ",found_obj)
        flag= False
else:
    print ('Status flag ::', flag)

This is a slight variation of a loop structure I know by the name witness, since you're only interested in a single "witness" to testify 3 is on the list of objects. Once you found this witness (which is the element 3).

Reut Sharabani
  • 30,449
  • 6
  • 70
  • 88
  • Since there is no `break` in OP’s code, there is nothing really wrong with that. – poke Jan 04 '15 at 16:34
  • 1
    Your first sentence makes it appear as if the code was failing because of the `else` but since OP isn’t breaking from the loop, there is nothing wrong with using the `else`. And OP is well-aware of that restriction. – poke Jan 04 '15 at 16:41