8

I am a beginner in python, and I was playing around with lambda functions. I was writing a program using lambda function to print characters that are +1 the ascii value of the input characters. My code is

#!/usr/bin/python
import sys
try:
  word = sys.argv[1]
except:
  print "No arguments passed"
  sys.exit(1)

def convert_ascii(char):
  return  "".join(chr(ord(char) + 1))

for i in word:
  print convert_ascii(i)
  print lambda x: chr(ord(i) + 1)

I have a function convert_ascii that does the same thing as lambda. However, my output is

/usr/bin/python2.7 /home/user1/PycharmProjects/test/Tut1/asciipl2.py "abc def ghi"
b
<function <lambda> at 0x7f0310160668>
c
<function <lambda> at 0x7f0310160668>
d
<function <lambda> at 0x7f0310160668>
!
<function <lambda> at 0x7f0310160668>
e
<function <lambda> at 0x7f0310160668>
f
<function <lambda> at 0x7f0310160668>
g
<function <lambda> at 0x7f0310160668>
!
<function <lambda> at 0x7f0310160668>
h
<function <lambda> at 0x7f0310160668>
i
<function <lambda> at 0x7f0310160668>
j
<function <lambda> at 0x7f0310160668>

The purpose of this script is learning lambda, though there are other ways to do this program. Please let me know what am I doing wrong. Process finished with exit code 0

pkill
  • 401
  • 1
  • 4
  • 11

5 Answers5

7

You aren't calling the function. It's the same as if you wrote print convert_ascii instead of print convert_ascii(i).

Try

print (lambda x: chr(ord(x) + 1))(i)

Note that I changed ord(i) to ord(x) in the function body.

saulspatz
  • 5,011
  • 5
  • 36
  • 47
  • 1
    Although fo note that in this case the Lambda is useless. The code in this answer is equivalent to `print(chr(ord(x) + 1))` – Azsgy Sep 19 '15 at 16:05
  • 4
    The OP's stated purpose is to learn how lambda expressions work. Where it is *appropriate* to use them is off-topic for this particular question. – chepner Sep 19 '15 at 16:06
  • Though I used i instead of x in lambda functions, the result was the same. In lambda, I accepted the var as x, but iterated as i, and still it worked. Any idea why? – pkill Sep 19 '15 at 16:11
  • 1
    Since the lambda expression is defined and called in the same scope, the `i` as a free variable in the expression is bound to the same value as `x` once the expression is called. It's technically a bug, but under the circumstances works the same as the correctly written code. – chepner Sep 19 '15 at 16:15
  • Thanks @chepner. This really helped. – pkill Sep 19 '15 at 16:18
4

The Lambda Keyword returns an anonymous function:

>>> func = lambda x: x+1
>>> print(func)
<function <lambda> at 0x7f0310160668>

the above is (not counting the behind-the-scenes magic) equivalent to:

>>> def func(x):
        return x+1

>>> print(func)
<function func at 0x7fa73d3e6bf8>

to invoke the function, lambda or not, you still have to call it:

>>> print(func)
<function <lambda> at 0x7f0310160668>
>>> func(123)
124

That said, Lambdas are not very well suited to this situation, and are better used if a function or construct requires a short function.

>>> word = "spam"
>>> map(lambda x: chr(ord(x) + 1), word)
Adam Jonas
  • 164
  • 1
  • 11
Azsgy
  • 3,139
  • 2
  • 29
  • 40
  • @chepner, yeah, just caught that. Will change to OP's example. Yes, list comprehensions would be better. – Azsgy Sep 19 '15 at 16:07
3

Currently you are printing a function object. You have to call the function.

Receive the function in a variable and call it with a parameter.

for i in word:
  print convert_ascii(i)
  fun=lambda x: chr(ord(x) + 1)
  print fun(some_arg) 
chepner
  • 497,756
  • 71
  • 530
  • 681
Ahsanul Haque
  • 10,676
  • 4
  • 41
  • 57
  • 3
    Correct. But saving lambda to a variable looks like creating a named function that is vice versa to lambda idea. For example, QuantifiedCode.com service treats it as an anti-pattern raising a warning. – Vasily Ryabov Sep 19 '15 at 15:55
  • 3
    You don't need to assign the function to a variable; `print (lambda x: chr(ord(x) + 1))(i)` works the same. – chepner Sep 19 '15 at 16:00
  • 1
    A lambda is a literal function. It doesn't have to be anonymous. One might equally well say that giving a name to a literal string or a literal number is an "anti-pattern". – saulspatz Sep 19 '15 at 16:01
  • I know, it's basiclly matter of calling the function. – Ahsanul Haque Sep 19 '15 at 16:01
  • 4
    Lambdas are intended for situations where you can't or don't need to assign a name. If you're going to write `foo = lambda x: ...`, you may as well write `def foo(x): ...`. I can't think of a situation where you would use a lambda expression with a list comprehension. – chepner Sep 19 '15 at 16:03
  • `[(lambda x: x*x)(x) for x in range(10)]` can't you write that? – Ahsanul Haque Sep 19 '15 at 16:05
  • 1
    You could, but why would you? `[x*x for x in range(10)]` – chepner Sep 19 '15 at 16:07
  • @chepner You're right, but I think the OP is just trying to figure out how lambdas work in python, don't you? – saulspatz Sep 19 '15 at 16:20
  • I do, but you're the one who brought up using a lambda expression in a list comprehension. – chepner Sep 19 '15 at 16:22
  • @chepner. I think you're confusing me with Ahsanul Hasque. I didn't say anything about list comprehensions. I may have scrolled down too fast. I thought you were talking about the OP's code, not Ahsanul's. – saulspatz Sep 19 '15 at 16:27
1

You are trying to print the function itself. Instead of that, assign the function in a variable, and pass the parameter to the variable, or use the same within print itself.

for i in word:
  z = lambda x: chr(ord(x) + 1)
  print z(i)

or

for i in word:
  print (lambda x: chr(ord(x) + 1))(i)

or to learn map, you can use map to get the same result

for i in word:
  print "".join(map(lambda x: chr(ord(x) + 1), i))
nohup
  • 3,105
  • 3
  • 27
  • 52
0

Here is the I code tried just to show how to invoke the lambda function. but you can achieve the same output without using lambda. just chr(ord(i) + 1) gives the output you want.

word = 'py'

for i in word:
    print((lambda: chr(ord(i) + 1) )(), end='')
    # used lambda function as '(lambda)()' format to invoke on the spot

OR

word = 'py'

for i in word:
    fun = lambda: chr(ord(i) + 1) 
    print(fun(),end='')
    # assigning lambda function to a varibale and then invoking by suffising () with fun

Output:

qz

if you want to keep arguement in lambda then you have to pass the parameter or assign the value or variable to arguements otherwise it will raise an error example:

for i in word:
    fun = lambda x=i:do somethibng
    print(fun()) #invoked

and also you can pass the parameter in this way -> '(lambda function)(parmater)'

CrackerKSR
  • 1,380
  • 1
  • 11
  • 29