Max
Max

Reputation: 857

Why is my python loop not breaking?

I wrote a recursive function to walk through a JSON string that is loaded to a python dict. I am trying to stop when I find the final desired key in the JSON structure. I explicitly have a break statement in that spot but it appears not to be breaking. I am stumped as to why this continues. I have included the output below but this is a working python2 example. I put the sample JSON string in a gist.

import urllib2
import json

# This is loading the JSON
url ="https://gist.githubusercontent.com/mroth00/0d5c6eb6fa0a086527ce29346371d8ff/raw/700d28af12184657eabead7542738f27ad235677/test2.json"
example = urllib2.urlopen(url).read()
d = json.loads(example)

# This function navigates the JSON structure
def j_walk(json_input,dict_keys):
    for key, values in json_input.items():
        #print(index)
        if (key != dict_keys[0]):
            print("passing")
            print(key)
            continue
        elif ((key == dict_keys[0]) and (len(dict_keys)>1) and (values is None)):
            return 'missingValue'
        elif ((key == dict_keys[0]) and (len(dict_keys)==1) and (values is None)):
            return 'missingValue'
        elif ((key == dict_keys[0]) and (len(dict_keys)==1)):
            print(key)
            print(dict_keys[0])
            print(len(dict_keys))
            print("i made it")
            print values
            break
        elif ((key == dict_keys[0]) and (len(dict_keys)>1)):
            print(len(dict_keys))
            #print(values)
            j_walk(values,dict_keys[1:])
        else:
            return 'somethingVeryWrong'

# Run the function here:
j_walk(d,['entities','hashtags'])

Output, it should break after "i made it" and printing the value but it keeps going:

passing
user
passing
truncated
passing
text
passing
created_at
2
passing
symbols
passing
user_mentions
hashtags
hashtags
1
i made it
[{u'indices': [103, 111], u'text': u'Angular'}]
passing
id_str
passing
id
passing
source

Upvotes: 0

Views: 62

Answers (2)

PRMoureu
PRMoureu

Reputation: 13327

The issue comes from this block, where you call j_walk recursively, the break statement only stops this recursion, then the initial loop continues :

elif ((key == dict_keys[0]) and (len(dict_keys)>1)):
    print(len(dict_keys))
    j_walk(values,dict_keys[1:]) # beginning of a second loop

    #You need some break here to stop this evil loop
    break

Upvotes: 1

lenik
lenik

Reputation: 23536

break breaks the for loop, but not recursively called j_walk() functions.

Please, use recursion with caution =)

You may create a global flag done, set it to False and then to True once you've found whatever you're looking for. And inside every for loop insert the statement if done : break -- this will quickly break 'em all.

Upvotes: 0

Related Questions