Python lambda函数打印<function <lambda> at 0x7fcbbc740668>而不是值

9

我是Python的初学者,最近在使用lambda函数进行编程。 我写了一个程序,使用lambda函数打印输入字符的ascii值+1的字符。我的代码如下:

#!/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)

我有一个名为convert_ascii的函数,它和lambda做的事情是一样的。然而,我的输出结果是

/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>

这个脚本的目的是学习lambda,虽然还有其他实现此程序的方法。请告诉我我做错了什么。 进程以退出代码0完成。
5个回答

7

你没有调用函数。这就像你写了print convert_ascii而不是print convert_ascii(i)一样。

尝试:

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

请注意,我在函数体中将ord(i)更改为ord(x)

1
请注意,在这种情况下Lambda是无用的。此答案中的代码等同于print(chr(ord(x) + 1)) - Azsgy
4
OP的目的是学习lambda表达式的工作原理。在哪些情况下使用它们不属于这个问题的讨论范围。 - chepner
尽管我在lambda函数中使用了i而不是x,但结果仍然相同。在lambda中,我将变量接受为x,但作为i进行迭代,它仍然有效。有任何想法为什么? - pkill
1
由于lambda表达式在同一作用域中定义和调用,因此表达式中的自由变量i在调用表达式时绑定到与x相同的值。这在技术上是一个错误,但在这种情况下与正确编写的代码具有相同的功能。 - chepner
谢谢@chepner。这真的很有帮助。 - pkill

4
Lambda关键字返回一个匿名函数:
>>> func = lambda x: x+1
>>> print(func)
<function <lambda> at 0x7f0310160668>

上述内容(不计算幕后的魔术)相当于:

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

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

无论是使用lambda函数还是普通函数,你都需要调用它来执行:

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

话虽如此,Lambda表达式并不非常适合这种情况,最好在需要短函数的函数或构造时使用。

>>> word = "spam"
>>> map(lambda x: chr(ord(x) + 1), word)

@chepner,是的,我刚刚注意到了。将更改为OP的示例。是的,列表推导式会更好。 - Azsgy

3

目前你正在打印一个函数对象。你需要调用这个函数。

将函数存储在一个变量中,并使用参数调用它。

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

3
正确。但将lambda保存到变量中看起来像是创建一个与lambda理念相反的有名函数。例如,QuantifiedCode.com服务将其视为反模式并发出警告。 - Vasily Ryabov
3
不必将函数赋值给一个变量;print (lambda x: chr(ord(x) + 1))(i) 的效果是一样的。 - chepner
1
Lambda是一个字面上的函数。它不一定是匿名的。同样地,给字面上的字符串或数字命名也被称为“反模式”。 - saulspatz
4
Lambda表达式适用于那些不需要或不想给函数命名的情况。如果你要写foo = lambda x: ...,那么你可以写成def foo(x): ...。我想不出在列表推导式中使用lambda表达式的情况。 - chepner
1
你可以这样做,但为什么要这样做呢?[x*x for x in range(10)] - chepner
显示剩余5条评论

1
你正在尝试打印函数本身。相反,将函数分配给一个变量,并将参数传递给该变量,或者在print语句中直接使用该函数。
for i in word:
  z = lambda x: chr(ord(x) + 1)
  print z(i)

或者

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

或者学习地图时,你可以使用地图来获得相同的结果。

for i in word:
  print "".join(map(lambda x: chr(ord(x) + 1), i))

从来不知道。谢谢。 - pkill
列表推导式比在列表上映射用户定义函数更高效:[ chr(ord(x) + 1) for x in word] - chepner
谢谢chepner。我复制粘贴了,所以没有注意到。已更改。 - nohup

0

这里是我尝试展示如何调用lambda函数的代码。但是你可以不使用lambda来实现相同的输出,只需使用chr(ord(i) + 1)即可得到你想要的输出。

word = 'py'

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

或者

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

输出:

qz

如果你想在lambda中保留参数,那么你必须传递参数或将值或变量分配给参数,否则它会引发错误 例如:

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

同时,你也可以这样传递参数 -> '(lambda函数)(参数)'


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接