13

I am trying to calculate a postfix expression using Python, but it did not work. I think this is maybe a Python-related problem.

Any suggestions?

expression = [12, 23, 3, '*', '+', 4, '-', 86, 2, '/', '+']

def add(a,b):
    return a + b
def multi(a,b):
    return a* b
def sub(a,b):
    return a - b
def div(a,b):
    return a/ b


def calc(opt,x,y):
    calculation  = {'+':lambda:add(x,y),
                     '*':lambda:multi(x,y),
                     '-':lambda:sub(x,y),
                     '/':lambda:div(x,y)}
    return calculation[opt]()



def eval_postfix(expression):
    a_list = []
    for one in expression:
        if type(one)==int:
            a_list.append(one)
        else:
            y=a_list.pop()
            x= a_list.pop()
            r = calc(one,x,y)
            a_list = a_list.append(r)
    return content

print eval_postfix(expression)
jkdev
  • 11,360
  • 15
  • 54
  • 77
newlife
  • 778
  • 1
  • 6
  • 20
  • 3
    Totally unrelated to your question but 1/ you may want to read the doc for the `operator` module, and 2/ in your `calc` function you don't need lambdas at all - just map to the operator functions and pass arguments at call time, ie : `{"+": add, "-":sub,}[opt](x, y)`. This will also allow you to define the mapping globally hence avoiding building it again and again on each call to `calc`. – bruno desthuilliers Nov 16 '13 at 10:23
  • @brunodesthuilliers ,thanks, that`s wondeful!!! – newlife Nov 16 '13 at 10:48

8 Answers8

21

Just replace a_list = a_list.append(r) with a_list.append(r).

Most functions, methods that change the items of sequence/mapping does return None: list.sort, list.append, dict.clear ...

Not directly related, but see Why doesn’t list.sort() return the sorted list?.

falsetru
  • 357,413
  • 63
  • 732
  • 636
17

The method append does not return anything:

>>> l=[]
>>> print l.append(2)
None

You must not write:

l = l.append(2)

But simply:

l.append(2)

In your example, replace:

a_list = a_list.append(r)

to

a_list.append(r)
Maxime Chéramy
  • 17,761
  • 8
  • 54
  • 75
  • thank you very much for your quick answer and related discussion.there is only one gree V I can click,,, – newlife Nov 16 '13 at 09:52
6

For return data on append use:

b = []   
a = b.__add__(['your_data_here'])
coyote69
  • 61
  • 1
  • 3
  • That's nice - and i just replace `.append` with .__add__` in my code. It's a PITA that these `list` methods are not chainable. What would be the analogous equivalent of `.extend` ? – WestCoastProjects May 20 '19 at 22:10
1

append function mutates the list and it returns None. This is the piece of code which does that http://hg.python.org/cpython/file/aa3a7d5e0478/Objects/listobject.c#l791

listappend(PyListObject *self, PyObject *v)
{
    if (app1(self, v) == 0)
        Py_RETURN_NONE;
    return NULL;
}

So, when you say

a_list = a_list.append(r)

you are actually assigning a_list with None. So, the next time when you refer to a_list, it is not pointing to the list but the None. So, as others have suggested, change

a_list = a_list.append(r)

to

a_list.append(r)
thefourtheye
  • 233,700
  • 52
  • 457
  • 497
0

Functions like list.append(),list.sort() don't return anything. e.g

def list_append(p):
    p+=[4]

function list_append doesn't have an return statement.so when you run following statements:

a=[1,2,3]
a=list_append(a)
print a
>>>None

but when you run following statements:

a=[1,2,3]
list_append(a)
print a
>>>[1,2,3,4]

That's it.so,hoping it can help you.

Tj L
  • 69
  • 5
0

List methods can be divided in two types those who mutate the lists in place and return None (literally) and those who leave lists intact and return some value related to the list.

First category:

append
extend
insert
remove
sort
reverse

Second category:

count
index

The following example explains the differences.

lstb=list('Albert')
lstc=list('Einstein')

lstd=lstb+lstc
lstb.extend(lstc)
# Now lstd and lstb are same
print(lstd)
print(lstb)

lstd.insert(6,'|')
# These list-methods modify the lists in place. But the returned
# value is None if successful except for methods like count, pop.
print(lstd)
lstd.remove('|')
print(lstd)

# The following return the None value
lstf=lstd.insert(6,'|')
# Here lstf is not a list.
# Such assignment is incorrect in practice.
# Instead use lstd itself which is what you want.
print(lstf)

lstb.reverse()
print(lstb)

lstb.sort()
print(lstb)

c=lstb.count('n')
print(c)

i=lstb.index('r')
print(i)

pop method does both. It mutates the list as well as return a value.

popped_up=lstc.pop()
print(popped_up)
print(lstc)
srinivasu u
  • 1,393
  • 11
  • 12
0

just a thought, instead of those functions (which manipulates the actual data) returning None, they should have returned nothing. Then atleast the user would have caught the issue as it would have throwed an error stating some assignment error!! Comment your thoughts!!

ItsPrinceAk
  • 102
  • 7
0

Just in case somebody ends here, I encountered this behavior while trying to append on a return call

This works as expected

def fun():
  li = list(np.random.randint(0,101,4))
  li.append("string")
  return li

This returns None

def fun():
  li = list(np.random.randint(0,101,4))
  return li.append("string")
Matias Andina
  • 4,029
  • 4
  • 26
  • 58