简体   繁体   中英

Python scopes in For -Else

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

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)

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

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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