Théo
Théo

Reputation: 31

How to convert '+' into + in Python

I'm willing to make a program that evaluates all possible combinations of operations ( + , - , * , / ) on a set of positive integers of length 6 (eg : [1, 6, 3, 9, 2, 9] ).

To do so, I am using the list

symbols = ['+', '-', '*', '/']

and wrote a nested loop to create all possibilities

+ + + + +
+ + + + -
.
.
.
/ / / / *
/ / / / /

by calling each row (eg : + - + * / ) a motif, and M the set of all motifs where

M[0] = ['+', '+', '+', '+', '+']
M[1] = ['+', '+', '+', '+', '-']

and so on. My goal now would be to write a function

evaluate_expression(motif, a, b, c, d, e, f)

that spits out the result of the expression a motif[0] b motif[1] c motif[2] d motif[3] e motif[4] f

my idea was to try converting '+' into the symbol + but I couldn't find a way to do it, I hope some of you guys here would know how to do that, I'm open to any suggestion of modification to make this cleaner.

Upvotes: 2

Views: 347

Answers (4)

haschtl
haschtl

Reputation: 119

You can execute strings with eval("...").

def evaluate_expression(operands, operators):
    assert len(operands)==len(operators)+1
    expression = str(operands[0])
    for idx, operator in enumerate(operators):
        expression += str(operator)+str(operands[idx+1])
    return eval(expression)

The function can be called like this evaluate_expression([1,2,3,4,5],["+","-","+","-"]) and will calculate 1+2-3+4-5 = -1

Upvotes: -1

Hamzah Bawah
Hamzah Bawah

Reputation: 21

I don't think there's a direct way to typecast a string to an operator (at least in the core python library) but what you could do is create the whole expression as a string and run eval() whiles passing it in.

opnd = [1, 6, 3, 9, 2]
oprt = ['+', '-', '*', '/']

def string_eval(operands,operators):
    final_string = ""
    for i in range(len(operands)):
        final_string += str(operands[i])
        if i < len(operators):
            final_string += str(operators[i])
    return eval(final_string)

print(string_eval(opnd,oprt))

Output -6.5

Upvotes: -1

Zachary Cross
Zachary Cross

Reputation: 2318

The operator library gives you functions for the basic operators (e.g. add(), sub())

So, you could replace your symbols = ['+', '-', '*', '/'] with:

from operator import add, sub, mul, truediv
symbols = [add, sub, mul, truediv]

and now your motif-generating function should make lists of functions instead of lists of strings.

Then, assuming you have a motif list, as you call it (check out itertools.combinations_with_replacement() for a function to generate all motifs), you can apply it by doing something like:

motif = [add, add, sub]
values = [5, 6, 7, 8]
 
result = values[0]
for i, current_func in enumerate(motif):
    result = current_func(result, value[i+1])

print(result)

Note: this method will not respect order of operations, it will apply the functions in order, left to right.

Upvotes: 4

lennihein
lennihein

Reputation: 81

Using a Dictionary of function pointers seeems to be what you want to use.

from operator import add, sub, mul, truediv

operators = {
    '+': add,
    '-': sub,
    '*': mul,
    '/': truediv
}


def op(operator, a, b):
    return operators[operator](a, b)


print(op('+', 1, 2))
print(op('-', 1, 2))

In total, it could look like this:

from operator import add, sub, mul, truediv

operators = {
    '+': add,
    '-': sub,
    '*': mul,
    '/': truediv
}


def op(operator_list, param_list):
    assert len(operator_list)+1 == len(param_list)
    assert len(param_list) > 0
    res = param_list[0]
    for i in range(len(operator_list)):
        res = operators[operator_list[i]](res, param_list[i])
    return res


print(op(['+', '-'], [1, 2, 4]))

Upvotes: 2

Related Questions