在lambda中使用print

4 投票
4 回答
17570 浏览
提问于 2025-04-17 20:56

我想在lambda表达式里使用print,像这样:

lambda x: print x

我知道在Python 2.7中,print不是一个函数。所以,我的问题是:有没有什么好办法可以在Python 2.7中把print当作函数来用呢?

4 个回答

1

我想大家可能还会对另一个场景感兴趣:“打印出lambda函数变量的中间步骤值”。

比如说,我想知道一组字符列表的字符集是什么:

In [5]: instances = [["C","O","c","1","c","c","c","c","c","1","O","C","C","N","C"],
   ...: ["C","C","O","C","(","=","O",")","C","C","(","=","O",")","c"],
   ...: ["C","N","1","C","C","N","(","C","c","2","c","c","c","(","N"],
   ...: ["C","l","c","1","c","c","c","2","c","(","N","C","C","C","["],
   ...: ["C","C","c","1","c","c","c","(","N","C","(","=","S",")","N"]]

一种实现这个的方式是使用reduce:

def build_charset(instances):
    return list(functools.reduce((lambda x, y: set(y) | x), instances, set()))

在这个函数中,reduce使用了一个带有两个变量x, ylambda函数。起初我以为它会像x -> instancey -> set()那样。但它的结果却让我大吃一惊,所以我想实时打印出它们的值。然而,lambda函数只能接受一个表达式,而打印又会引入另一个表达式。

受到set(y) | x的启发,我尝试了这个,结果成功了:

lambda x, y: print(x, y) or set(y) | x

注意,print()的返回值是NoneType,所以你不能使用andxor这些会改变原始值的操作。但在我的情况下,or是可以正常工作的。

希望这对那些也想在过程中看到发生了什么的人有帮助。

4

如果你不想使用 import from __future__ 这个功能,你可以让 lambda 直接输出到标准输出,也就是屏幕上:

>>>import sys
>>>l = lambda x : sys.stdout.write(x)
>>>l('hi')
'hi'
8

这个问题是关于Python 2的,但我从谷歌搜索中找到了这里,想在Python 3中使用lambda里的print函数。我添加这个回答是为了给其他有同样问题的人提供一些背景信息。

如果你只想看能用的代码,而不想了解我是怎么到这一步的,可以直接跳到最后的代码示例。为了学习的目的,我想清楚地记录一下哪些方法不奏效。

想要的结果

假设你想定义一个lambda print_list,它可以打印出列表中的每个项目,并且每个项目之间有换行。

lst = [1, 2, 3]

print_list = lambda lst: ...

期望的输出是:

1
2
3

而且不应该有未使用的返回值。

尝试1 - 在Python 3中,map不执行print函数

首先,这里是一些在Python 3中不太好用的代码:

map(print, lst)

然而,输出结果有点反直觉,并没有打印出每一行,因为在Python 3中,map调用< a href="https://stackoverflow.com/a/1303354/149428">返回的是一个迭代器,而不是一个已评估的列表。

输出:

n/a

返回值:

<map at 0x111b3a6a0>

尝试2 - 评估map迭代器

你可以通过将map的结果传递给list(...)来实现打印,这样可以得到理想的输出,但会有一个副作用,就是返回一个空值的列表(在REPL中评估时会看到)。

list(map(print, lst))

输出:

1
2
3

返回值:

[None, None, None]

你可以通过使用下划线丢弃变量的约定来解决这个问题:

_ = list(map(print, lst))

另一种类似的方法是在列表推导式中调用print:

[print(i) for i in lst]

我不太喜欢这些方法,因为它们仍然会生成一个未使用的返回值。

尝试3 - 对map迭代器应用解包操作符

像这样:

[*map(print, [1, 2, 3])]

(这仍然返回一个空值的列表,这并不是理想的结果。)

在上面的评论中,@thefourtheye建议使用一行的for循环:

for item in [1, 2, 3]: print(item)

这在大多数情况下都能正常工作,并且避免了副作用。尝试把这个放进lambda里会抛出一个语法错误。我试着用括号包裹它,但没有成功;虽然可能有办法做到这一点,但我还没搞明白。

(解决方案!)尝试4 - 在print调用中应用解包操作符

我找到的答案是在print调用中解开列表,同时使用分隔符参数:

print(*lst, sep='\n')

输出:

1
2
3

这样可以得到预期的结果,并且没有返回值。

最后,让我们把它封装成一个lambda,以便按需使用:

print_list = lambda lst: print(*lst, sep='\n')
print_list([1, 2, 3])

这是我在Python 3中最好的解决方案。

相关问题

10

你可以从 __future__ 这个模块里导入 print_function,然后像这样使用它作为一个函数

from __future__ import print_function
map(print, [1, 2, 3])
# 1
# 2
# 3

撰写回答