在lambda中使用print
我想在lambda表达式里使用print,像这样:
lambda x: print x
我知道在Python 2.7中,print不是一个函数。所以,我的问题是:有没有什么好办法可以在Python 2.7中把print当作函数来用呢?
4 个回答
我想大家可能还会对另一个场景感兴趣:“打印出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, y
的lambda
函数。起初我以为它会像x -> instance
和y -> set()
那样。但它的结果却让我大吃一惊,所以我想实时打印出它们的值。然而,lambda
函数只能接受一个表达式,而打印又会引入另一个表达式。
受到set(y) | x
的启发,我尝试了这个,结果成功了:
lambda x, y: print(x, y) or set(y) | x
注意,print()
的返回值是NoneType,所以你不能使用and
、xor
这些会改变原始值的操作。但在我的情况下,or
是可以正常工作的。
希望这对那些也想在过程中看到发生了什么的人有帮助。
如果你不想使用 import from __future__
这个功能,你可以让 lambda
直接输出到标准输出,也就是屏幕上:
>>>import sys
>>>l = lambda x : sys.stdout.write(x)
>>>l('hi')
'hi'
这个问题是关于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中最好的解决方案。
相关问题
你可以从 __future__
这个模块里导入 print_function
,然后像这样使用它作为一个函数
from __future__ import print_function
map(print, [1, 2, 3])
# 1
# 2
# 3