Emil Brundage
Emil Brundage

Reputation: 213

Returning a list of dictionaries from a recursive function fails

I have developed a function that is supposed to return a list of dictionaries. However, it returns None instead. When I test the code to return something else it works fine. Why does the list of dictionaries fail?

Pertinent code:

def FindCommonPhrases (liPhrases, liWords, maxIteration, dictionaries = [], iteration = 0):
    iteration += 1
    if iteration > maxIteration:
        print dictionaries
        return dictionaries
    #Other code here

dicts = FindCommonPhrases (phrases, listOfWords, numWords)
print dicts

results:

[{u'REPAIR': 4397, u'RENEWED': 192, u'212': 398, u'COUPLI': 5411, u'TR': 3357, u'OVER': 304, u'2PL': 2972, u'BJ': 1677, u'1OF': 130, u'STREET': 354, u'ELBOW': 188, u'CONT': 530, u'LINE': 275, u'WITH': 5019, u'BY': 1052, u'24': 483, u'STUB': 233, u'PIECE': 125, u'20': 234, u'COUPLING': 5146, u'RR': 730, u'WAS': 132, u'METER': 458, u'RETHREADED': 121, u'12CU': 327, u'4': 10292, u'8': 3133, u'REP': 25908, u'CLAMP': 596, u'DAMAGED': 918, u'FULL': 172, u'OFF': 524, u'FIT': 2088, u'COUPLIN': 5282, u'SVC': 4649, u'15': 252, u'P': 39866, u'DEAD': 302, u'RERUN': 419, u'X': 1227, u'THE': 284, u'TRANS': 445, u'34STEEL': 181, u'ON': 9645, u'BROKEN': 352, u'OF': 12452, u'14PL': 342, u'W12': 459, u'KIT': 438, u'JOINT': 1068, u'LOWERED': 196, u'W2': 313, u'W1': 737, u'METFIT': 299, u'CIRCLE': 162, u'MAIN': 3127, u'COUP': 6916, u'USED': 456, u'COUPL': 5760, u'BELL': 1183, u'HP': 202, u'CHANGED': 142, u'PLASTIC': 4135, u'DOWN': 333, u'114': 307, u'PERFECTION': 1330, u'M2': 382, u'COUPS': 315, u'AVON': 146, u'INSERTED': 4283, u'SERV': 9149, u'SERT': 7458, u'MADE': 141, u'CRACKED': 135, u'RERAN': 1836, u'ALDYL': 447, u'PB': 413, u'34STL': 257, u'3': 5758, u'7': 650, u'AMP': 873, u'PERMA': 3781, u'PL': 31660, u'PLUG': 216, u'C': 37103, u'END': 450, u'PERMABOND': 2269, u'FOR': 245, u'GREASED': 107, u'PERMACERT': 109, u'CORRODED': 138, u'W': 11440, u'GM': 220, u'PERF': 1910, u'AND': 3128, u'22': 334, u'LEAK': 2218, u'30': 315, u'ELECTROFUSION': 258, u'34': 2849, u'INSTD': 660, u'INSTL': 208, u'RISER': 3760, u'REMOVED': 265, u'REPAIRED': 2581, u'STEEL': 1397, u'COU': 7061, u'SERVICE': 8222, u'SECTION': 1086, u'VALVE': 2088, u'STOP': 361, u'REPR': 183, u'2OF': 208, u'12PL': 2669, u'FUSION': 896, u'REPL': 20704, u'CURB': 176, u'PERM': 4024, u'SERVICES': 182, u'NEW': 1791, u'REBUILT': 248, u'ELECTRO': 550, u'REG': 268, u'SET': 504, u'OLD': 358, u'SER': 18071, u'LEAKING': 1335, u'TEE': 3989, u'REPLACE': 16472, u'PIPE': 6570, u'2': 19616, u'REPLACED': 14670, u'6': 2146, u'COCK': 348, u'LEAKAGE': 140, u'OUT': 755, u'CI': 1599, u'CUT': 1339, u'CO': 9649, u'ABANDONED': 132, u'DUE': 245, u'FITTING': 966, u'ALDYLA': 168, u'EXISTING': 159, u'TR418': 1346, u'CU': 2726, u'PERMASERT': 937, u'10': 504, u'12': 12120, u'FITTINGS': 287, u'14': 3276, u'STOPCOCK': 163, u'16': 533, u'18': 2266, u'TRANSITION': 245, u'WELDED': 409, u'ST': 17811, u'MET': 1321, u'TIGHTENED': 165, u'BRANCH': 430, u'SQUEEZED': 225, u'USING': 754, u'SEAL': 365, u'REPAIRS': 182, u'1PL': 396, u'CAP': 1036, u'TWO': 822, u'BAD': 123, u'INST': 10214, u'INSTALL': 5966, u'CREW': 169, u'COUPLINGS': 3255, u'PREFAB': 244, u'INSERT': 6324, u'WELD': 633, u'12PLASTIC': 133, u'GAS': 1936, u'ONE': 600, u'1': 20805, u'TO': 3334, u'5': 1676, u'LP': 482, u'A': 37589, u'COPPER': 625, u'STL': 2294, u'INTO': 316, u'HEAT': 168, u'AT': 1612, u'IN': 24552, u'FOUND': 150, u'112': 305, u'125': 134, u'INSERTING': 175, u'FROM': 408, u'SLEEVE': 233, u'PERMABONDED': 1317, u'INSTALLED': 5239, u'CILP': 207, u'21': 666, u'T': 31607}]
None

Test code:

def FindCommonPhrases (liPhrases, liWords, maxIteration, dictionaries = [], iteration = 0):
    iteration += 1
    if iteration: #> maxIteration:
        print dictionaries
        return dictionaries
    #Other code here

dicts = FindCommonPhrases (phrases, listOfWords, numWords)
print dicts

Test results:

[]
[]

What's going wrong?

More pertinent code:

phrases = ["phrase", "another phrase...", "etc etc"]
listOfWords = ["word1", "another", "word", "etc"]
numWords = 2

def FindCommonPhrases (liPhrases, liWords, maxIteration, dictionaries = [], iteration = 0):
    iteration += 1
    if iteration > maxIteration:
        print dictionaries
        return dictionaries
    liCombos = list(itertools.combinations(liWords, iteration))
    di = {}
    for liCheck in liCombos:
        phrase = " ".join (liCheck)
        for checkPhrase in liPhrases:
            if not phrase in checkPhrase:
                continue
            if phrase in di:
                di[phrase]  += 1
            else:
                di[phrase]  = 1

    dictionaries += [di]

    FindCommonPhrases (liPhrases, liWords, maxIteration, dictionaries, iteration)

dicts = FindCommonPhrases (phrases, listOfWords, numWords)
print dicts

Upvotes: 0

Views: 85

Answers (1)

tobias_k
tobias_k

Reputation: 82899

You are calling the function recursively, but not returning the result from the recursive call.

def FindCommonPhrases (liPhrases, liWords, maxIteration, dictionaries = [], iteration = 0):
    iteration += 1
    if iteration > maxIteration:
        return dictionaries
    # more code here
    FindCommonPhrases (liPhrases, liWords, maxIteration, dictionaries, iteration)

Change the last line to return the result, then it should work.

    return FindCommonPhrases (liPhrases, liWords, maxIteration, dictionaries, iteration)

Also note that using a default-parameter like dictionaries = [] is usually a bad idea, as this will use the same list for each call of the function! Just see what happens if you invoke you function twice. Try this instead:

def FindCommonPhrases(liPhrases, liWords, maxIteration, dictionaries=None, iteration=0):
    if dictionaries is None:
        dictionaries = []
    # more stuff

Upvotes: 1

Related Questions