I was trying to come up with a dictionary of functions, but get it not to work.

Dani AI

Generated

A few concise, practical ways to make a "dictionary of functions" robust and Python‑3 friendly — building on what , , and showed.

Storing callables in a dict and looking them up is fine; for a production-ready helper you want (1) explicit handling of unknown symbols, (2) support for common math synonyms (if you choose), and (3) safe error handling. The operator module is handy for this and in Python 3 use truediv / floordiv rather than the old div.

from operator import add, sub, mul, truediv, floordiv, mod, pow

_ops = {
    '+': add,    '-': sub,    '*': mul,
    '/': truediv, '//': floordiv, '%': mod,
    '**': pow
}

def calc(op, a, b):
    func = _ops.get(op)
    if func is None:
        raise ValueError("unsupported operator: {!r}".format(op))
    return func(a, b)

A couple of useful extras not shown earlier: create pre-bound helpers with functools.partial (useful for callbacks or UI buttons), map non‑Python symbols deliberately (for example map '^' → pow only if you document that it's treated as exponent, since in Python ^ is XOR), and prefer raising clear exceptions rather than silently printing errors.

Avoid eval for user input; validate/normalize operator strings (strip whitespace, reject unexpected characters), and catch specific exceptions like ZeroDivisionError where you need custom behavior. For financial or exact rational math consider decimal.Decimal or fractions.Fraction instead of floats.

These small additions keep the pattern shown by and simple, make ’s getattr idea and ’s operator-module suggestion practical in real code, and prevent the common pitfalls that tripped up .

Recommended Answers

All 9 Replies

Sorry, mindreading is not my métier. Please gives us an example of your code and the error message you get.

You mean something like this?

import re
f = dict()
f["compile"] = re.compile
f["findall"] = re.findall
f["match"] = re.match
pattern = f["compile"]("[\\w]+")

This works for me.

Thanks G-Do! I think you gave me a good hint where i went wrong. Here is my error prone code:

# a dictionary of functions by bumsfeld
# get errors = TypeError: 'int' object is not callable

def add(a, b):
    return a + b

def sub(a, b):
    return a - b

def mul(a, b):
    return a * b

def div(a, b):
    return a / b

a = b = 1

mathD = {
'+' : add(a, b),
'-' : sub(a, b),
'*' : mul(a, b),
'/' : div(a, b)
}

f = mathD['+']
print f(99, 13)

G-Do did give you the hint, don't call the functions from the dictionary, just reference them. I took the liberty to play with your code a little ...

def add(a, b):
    return a + b

def subtract(a, b):
    return a - b

def multiply(a, b):
    return a * b

def divide(a, b):
    if b == 0:
        print "divide by zero error"
    else:
        return a / b

# use the function reference, not the actual call
mathD = {
'+' : add,
'-' : subtract,
'*' : multiply,
'/' : divide
}


f = mathD['+']
print f(99, 13)

# or simpler ...
print mathD['+'](99, 13)

# maybe less cryptic ...
def calc(math_op, a, b):
    return mathD[math_op](a, b)

# now you can use ...
print calc('/', 355, 113.0)

How can you handle the wrong symbol? Like someone uses '**' and not '*'

That's where the calc() function would come in handy, change it to ...

def calc(math_op, a, b):
    if math_op in mathD:
        return mathD[math_op](a, b)
    else:
        print "'%s' not recognized" % math_op

That is not necessarily the OP's actual question,
(does not even have a dictionary of functions)
but I was facing the problem that I needed something like the calc function
that vegaseat suggested and this is what I came up with:

mathD = {
    '+': '__add__',
    '-': '__sub__',
    '*': '__mul__',
    '/': '__div__'
}

def calc(op, a, b):
    method = getattr(a,mathD[op])
    return method(b)

Saves me writing down all the defs :D

Thanks for the tip. Now it look even better. (And I am using a dictionary of functions.)

from operator import add, sub, mul, div

mathD = {
    '+': add,
    '-': sub,
    '*': mul,
    '/': div
}

def calc(op, a, b):
    return mathD[op](a,b)
Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.