0

I'm trying to make a dictionary which contains functions as the values. The idea is that the difficulty variable will change throughout the program, and this will affect which function we call from the dictionary. For the sake of this, I'm not going to show the program, I've made a simple mock up that demonstrates the issue I'm having.

Whenever I run the code, without even entering a key, it runs the functions. Why is this?

def printhello():
    print("hello")

def printgoaway():
    print("go away")


x={1:printhello(),2:printgoaway()}

At this point I wasn't expecting anything to have happened as I haven't called any keys yet. It runs the functions anyway and prints the values.

If I then call them by doing x[1] or x[2], nothing happens.

Can someone explain to me how I would use functions in a dictionary, and stop them from automatically calling them when I make the dictionary

martineau
  • 119,623
  • 25
  • 170
  • 301
  • "At this point I wasn't expecting anything to have happened as I haven't called any keys yet." One does not call keys. One calls *functions*, which you did here: `printhello()` and here: `printgoaway()`. In other words, the values in your dictionary are not the function objects, they are the result of *calling* the function objects, which aren't functions at all. – juanpa.arrivillaga Jun 19 '19 at 22:40
  • Consider just looking up the functions in a class or module `__dict__`. But in that case, be sure to verify that they're functions you want, often by requiring a `cmd_` prefix or similar. – o11c Jun 19 '19 at 22:42

3 Answers3

3

When you put () after the function name, that tells Python to call the function immediately.

You should change your code to do this:

x={1:printhello,2:printgoaway}

So that your dictionary contains references to the functions, instead of the result of calling them up front.

Then you can call them later like this:

x[0]()

Note the brackets here, and lack of brackets in the previous line.

Blorgbeard
  • 101,031
  • 48
  • 228
  • 272
0

The problem is that you are placing parentheses after the function names in the dictionary:

x={1:printhello(),2:printgoaway()}

This executes the functions and puts the returned values into the dictionary. Try removing the parentheses:

x={1:printhello ,2:printgoaway}

This puts the functions themselves in the dictionaries.

As an example, here is a section of one of my programs:

OPERATIONS = {'+': sum, '*': rdmath.prod}

def evaluate_subtree(node_list, ndx: int) -> int:
    """Evaluate the subtree inside node_list with the root at ndx.
    Use recursion and postorder in depth first search."""
    this_payload, these_children = node_list[ndx]
    if not these_children:  # if a leaf node
        return int(this_payload)
    return OPERATIONS[this_payload](evaluate_subtree(node_list, child)
                                    for child in these_children)

Note that I put the sum function and rdmath.prod (which calculates the product of the members of an iterable) into the dictionary OPERATIONS. The last line of my snippet uses the dictionary to choose one of the two functions then executes the function on a generator comprehension, and the resulting value is returned. (So the values in the generator comprehension are either added or multiplied.)

Try something like that and see if it works for you.

Rory Daulton
  • 21,934
  • 6
  • 42
  • 50
0

printhello() runs printhello

use x={1:printhello, 2:printgoaway}to store your functions and x[1]() to call it

Raphael
  • 1,731
  • 2
  • 7
  • 23