Welcome, guest | Sign In | My Account | Store | Cart

This function creates a dictionary containing all of the variables passed as parameters with the variable name being the key and the value of the variable as the value. I use it frequently when passing parameters to another function.

Python, 28 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
from traceback import extract_stack

def makeDict(*args):
    strAllStack = str(extract_stack())
    intNumLevels = len( extract_stack() )
    intLevel = 0
    blnFinished = False
    while not blnFinished:
        strStack = str( extract_stack()[intLevel] )
        if strStack.find( "makeDict( ")>0:
            blnFinished = True
        intLevel += 1
        if intLevel >= intNumLevels:
            blnFinished = True
    strStartText = "= makeDict( "
    intLen = len( strStartText )
    intOpenParenLoc = strStack.find( strStartText )
    intCloseParenLoc = strStack.find(")", intOpenParenLoc )
    strArgs = strStack[ intOpenParenLoc+intLen : intCloseParenLoc ].strip()
    lstVarNames = strArgs.split(",")
    lstVarNames = [ s.strip() for s in lstVarNames ]   
    if len( lstVarNames ) == len( args ):
        tplArgs = map( None, lstVarNames, args )
        newDict = dict( tplArgs )
        return newDict
    else:
        print "Error.  makeDict Failed."
        return None

I created this function because I found the syntax for creating dictionaries a little cumbersome when all I wanted to do was quickly pack up a bunch of variables into a dictionary and then pass the newly created dictionary as a single parameter to various functions. It also allows you to add or subtract elements to the dictionary without having to worry about finding and changing the function definition and then all of the places where that function is called.

2 comments

Mariano Heredia 15 years, 9 months ago  # | flag

Hi Andrew! First of al, I would like toy say that your recipe seems to be very useful. I'm posting here some little improvements:

  • re pattern finding insted of str.find function (I found not so flexible the way the makeDict call were looked up)
  • removing len( lstVarNames ) and len( args ) equality constraint (maybe someone will want to build a partial arguments dictionary)

Here is the resulting code, and a couple of usage functions:

from traceback import extract_stack
import re

def makeDict(*args):
    strAllStack = str(extract_stack())
    #pattern of a makeDict call...
    makeDict_pattern = 'makeDict[ ]*\('
    #finding the last call to makeDict i.e. current call...
    last_ocurrence = list(re.finditer(makeDict_pattern, strAllStack))[-1]
    #finding args names...
    strStack = strAllStack[last_ocurrence.start():]
    strArgs = strStack[(strStack.find('(') + 1):strStack.find(')')].strip()
    lstVarNames = strArgs.split(',')
    lstVarNames = [ s.strip() for s in lstVarNames ]      
    #building dict
    tplArgs = map(None, lstVarNames, args)
    newDict = dict(tplArgs)
    return newDict


def my_func2(dict):
    print makeDict(dict)['dict']

def my_func(a,b,c):
    print makeDict(a,b,c)
    print makeDict(a,c)
    print makeDict()
    my_func2(makeDict       ( a , b ))

if __name__=='__main__':
    my_func ( 1 , 2 , 3)

Well, thanks for your recipe and I hope these changes helps.

Andrew Konstantaras (author) 15 years, 8 months ago  # | flag

Thanks, sorry it has taken me so long to respond. Both of your recommended changes are great. I believe your use of regexes is not only more elegant, but I think the added efficiency of your code outweighs the cost of loading the regex module. The conditional at the end was a error trap I put in as I ran into a some weird behavior when I was running the function at the command line versus running it from within a module (this was months ago, but I think it had something to do with the way frames were managed in the two different execution environments). After I got it working, I've never had the error pop up, so I should have gone back and deleted it.

Thanks again for taking the time to tweak it and I am glad to hear you find it useful. I use this little function in almost every project I work on.