BeNikis
BeNikis

Reputation: 13

Python TypeErrors: "' list' object is not callable" and "'function' object is unsubscriptable"

I have the following code:

from random import randint,choice

add=lambda x:lambda y:x+y
sub=lambda x:lambda y:x-y
mul=lambda x:lambda y:x*y


ops=[[add,'+'],[sub,'-'],[mul,'*']]

def gen_expression(length,left,right):
    expr=[]
    for i in range(length):
        op=choice(ops)
        expr.append([op[0](randint(left,right)),op[1]])
    return expr

def eval_expression (expr,x):
    for i in expr:
           x=i[0](x)
    return x

def eval_expression2 (expr,x):
    for i in expr:
           x=i(x)
    return x
[snip , see end of post]
def genetic_arithmetic(get,start,length,left,right):
    batch=[]
    found = False
    for i in range(30):
        batch.append(gen_expression(length,left,right))

    while not found:
        batch=sorted(batch,key=lambda y:abs(eval_expression(y,start)-get))
        print evald_expression_tostring(batch[0],start)+"\n\n"

                #combine                        
        for w in range(len(batch)):
            rind=choice(range(length))
            batch.append(batch[w][:rind]+choice(batch)[rind:])

            #mutate
        for w in range(len(batch)):
            rind=choice(range(length))
            op=choice(ops)
            batch.append(batch[w][:rind]+[op[0](randint(left,right)),op[1]]+batch[w][rind+1:])

        found=(eval_expression(batch[0],start)==get)

    print "\n\n"+evald_expression_tostring(batch[0],start)

When I try to call to call genetic_artihmetic with eval_expression as the sorting key, I get this:

 Traceback (most recent call last):
  File "<pyshell#113>", line 1, in <module>
    genetic_arithmetic(0,10,10,-10,10)
  File "/home/benikis/graming/py/genetic_number.py", line 50, in genetic_arithmetic
    batch=sorted(batch,key=lambda y:abs(eval_expression(y,start)-get))
  File "/home/benikis/graming/py/genetic_number.py", line 50, in <lambda>
    batch=sorted(batch,key=lambda y:abs(eval_expression(y,start)-get))
  File "/home/benikis/graming/py/genetic_number.py", line 20, in eval_expression
    x=i[0](x)
TypeError: 'function' object is unsubscriptable

And when I try the same with eval_expression2 as the sorting,the error is this:

Traceback (most recent call last):
  File "<pyshell#114>", line 1, in <module>
    genetic_arithmetic(0,10,10,-10,10)
  File "/home/benikis/graming/py/genetic_number.py", line 50, in genetic_arithmetic
    batch=sorted(batch,key=lambda y:abs(eval_expression2(y,start)-get))
  File "/home/benikis/graming/py/genetic_number.py", line 50, in <lambda>
    batch=sorted(batch,key=lambda y:abs(eval_expression2(y,start)-get))
  File "/home/benikis/graming/py/genetic_number.py", line 25, in eval_expression2
    x=i(x)
TypeError: 'list' object is not callable

As far as i can wrap my head around this, my guess is that sorted() is trying to recursively sort the sublists,maybe? What is really going on here?

Python version is 2.6 - the one in the debian stable repos.

[snip] here:

def expression_tostring(expr):
    expr_str=len(expr)*'('+'x '
    for i in expr :
        if i[1]=='*':
            n=i[0](1)
        else:
            n=i[0](0)
        expr_str+=i[1]+' '+str(n)+') '

    return expr_str

def evald_expression_tostring(expr,x):
    exprstr=expression_tostring(expr).replace('x',str(x))
    return exprstr+ ' = ' + str(eval_expression(expr,x))

Upvotes: 1

Views: 1605

Answers (2)

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 250881

    x=i[0](x)  #here i is a function so you can't perform indexing operation on it      


    x=i(x) #here i is a list so you can't call it as a function

in both cases the value of i is fetched from expr, may be expr contains different type of object than what you're assuming here.

Upvotes: 2

inspectorG4dget
inspectorG4dget

Reputation: 113905

Try this modification:

def gen_expression(length,left,right):
    expr=[]
    for i in range(length):
        op=choice(ops)
        expr.append([op[0], randint(left,right),op[1]])
    return expr

def eval_expression (expr,x):
    for i in expr:
           x=i[0](i[1])
    return x

You had expr.append([op[0](randint(left,right)),op[1]]) which will put the return value of the calling the function into the 0th index.

Upvotes: 0

Related Questions