MultipleCrashes
MultipleCrashes

Reputation: 63

How to reset a global variable in python "recursive" function?

def getValueForSpecificKey(self,capturedLog,key):

     ''' Get value from log for any specific key,caputredLog must be a string'''
     global Found
     global returnValue
     if type(capturedLog)==type({}):
         for eachKey in capturedLog:
             if eachKey==key:
                 Found=True
                 print "Found Key Match :",eachKey
                 print capturedLog[key]
                 listAppendValue=capturedLog[key]
                 #returnValue=capturedLog[key]
                 returnValue.append(listAppendValue)
                 print "="*1000
                 print "The value for key in the captured Log is -> ",capturedLog[key]
                 print " Return value "*10,(returnValue)
                 return Found,returnValue
             self.getValueForSpecificKey(capturedLog[eachKey],key)
     elif type(capturedLog) is list:
         for elements in capturedLog:
             self.getValueForSpecificKey(elements,key)
     print returnValue
     return Found,returnValue

I have this function which recursively iterated over a valid json.The json might contain dict or list.The function here searched takes some input log which is json and a key to search in the json.I am able to iterate to get all the keys in the json .Things are fine.

But the problem comes when I try to return the value.Since the returnValue is a global variable .Appending to the list ,keeps on appending all the values to the same list.Even when I create an object of the class from some other module and call this function the list still grows and I am not able to clear/reset the returnValue before/after the function call.I need to change the returnValue which is a list each time the object is created from external module i.e when the first time this function is called.So it is a problem where I need to return value with recursion.

Since the api is already defined I can only change the code within.

Please help. Thanks.

Upvotes: 1

Views: 3336

Answers (3)

MultipleCrashes
MultipleCrashes

Reputation: 63

Okay , Here is the solution

Default parameter values are evaluated when the function definition is executed. This means that the expression is evaluated once, when the function is defined, and that the same “pre-computed” value is used for each call. This is especially important to understand when a default parameter is a mutable object, such as a list or a dictionary: if the function modifies the object (e.g. by appending an item to a list), the default value is in effect modified. This is generally not what was intended. A way around this is to use None as the default, and explicitly test for it in the body of the function, e.g.:

def getValueForSpecificKey(self,capturedLog,key,First=None):

     ''' Get value from requests log for any specific key,caputredLog must be a string'''
     global Found
     global returnValue
     if First is None:
         First='notnone'
         Found=False
         returnValue=[]
         print "Return Value ->",returnValue
         print "Found - >",Found

     if type(capturedLog)==type({}):
         for eachKey in capturedLog:
             print eachKey
             if eachKey==key:
                 Found=True
                 print "Found Key Match :",eachKey
                 print capturedLog[key]
                 listAppendValue=capturedLog[key]
                 returnValue.append(listAppendValue)
                 print "="*1000
                 print "The value for key in the captured Log is -> ",capturedLog[key]
                 print " Return value "*10,(returnValue)
                 return Found,returnValue
             print "CapturedLog - >",capturedLog
             print "Calling using recursion "
             self.getValueForSpecificKey(capturedLog[eachKey],key,First)
     elif type(capturedLog) is list:
         for elements in capturedLog:
             self.getValueForSpecificKey(elements,key,First)
     return Found,returnValue

Upvotes: 1

Blckknght
Blckknght

Reputation: 104792

I think you should alter your recursive function to not need any global variables. If you only expect to find a single result, I think it's not too complicated.

def getValueForSpecificKey(self, capturedLog, key):
    '''
    Get value from log for any specific key.
    capturedLog will be searched if it is a list or dictionary.
    Returns None if the key is not found, or capturedLog is another type.
    '''

    if isinstance(capturedLog, dict):
        if key in capturedLog:                # base case #1 (found the key)
            return capturedLog[key]

        values = capturedLog.values()

    elif isinstance(capturedLog, list):
        values = capturedLog

    else:
        return None                           # base case #2 (not a list or dict)

    for value in values:
        result = self.getValueForSpecificKey(value, key)      # recursive case
        if result is not None:
            return result

    return None                               # nothing found in the recursive search

If you might have multiple values in different dictionaries with the desired key, you'll probably need to pass a list around:

def getValueForSpecificKey(self, capturedLog, key, results=None):
    '''
    Get value from log for any specific key.
    capturedLog will be searched if it is a list or dictionary.
    Returns an empty list if the key is not found, or capturedLog is another type.
    '''
    if results is None:
        results = []               # start a new list if this is a non-recursive call

    if isinstance(capturedLog, dict):
        if key in capturedLog:
            results.append(capturedLog[key])     # found a result, add it to the list
            return results

        values = capturedLog.values()

    elif isinstance(capturedLog, list):
        values = capturedLog

    else:
        return results

    for value in values:  # recursive calls will add to the results list as necessary
        self.getValueForSpecificKey(value, key, results)

    return results

Upvotes: 1

Gadi
Gadi

Reputation: 1152

def getValueForSpecificKey(self,capturedLog,key,first=[])
global returnaValue
if not first:
   first.append(1)
   returnaValue = []

This will create a global empty list the first time you call it. This will indicate you should clear the global list, returnValue. No api change and works with recursion

Upvotes: 0

Related Questions