在Python列表推导式中间调用print函数

3

我试图实现在这个网站上第一次听说的一个技巧。

[i for i in range(0, 10) if True or print(i)]

这个想法是你可以在列表推导式的每一步调用任意函数,只需将其放在一个始终返回True的“if”语句中。但是这段代码会报语法错误。

如果我这样封装要调用的函数:

def f(i):
    print i

[i for i in range(0, 10) if True or f(i)]

it产生了期望的输出。所以我想知道在Python看来,这两者之间有什么区别,因为我无法确定可能是什么——这两个函数都返回“None”,对吗?


2
from __future__ import print_function;但是为什么你需要有任何副作用呢? - Martijn Pieters
2
如果你实际上不需要列表,就不要使用列表推导式来代替for循环。 - chepner
3个回答

6

您不能在列表推导式中混合使用语句(例如Python 2中的print)。

但是,您可以通过添加以下内容将print()转换为函数:

from __future__ import print_function

print() 放在文件顶部,就能将其作为模块的函数使用。

然而,如果你使用语句 True or something ,'something' 永远不会被执行,因为 Python 的布尔表达式采用短路求值。你需要调整一下:

if print(something) or True

如果左边的值已经评估为True,则评估右边的or表达式没有意义;不管右边的值是什么,整个表达式都将永远为True。
在列表推导式中,确实应该避免这种副作用。使用适当的循环并将这些意外情况从您的代码中排除出去。使用"if something or True"是一个技巧,您真的要避免使用它,因为它会使未来的维护者(包括您自己)感到困惑。

啊,有道理。我不知道print()不是一个函数。而且你说的关于短路的事情也是对的:我提供的代码实际上并没有产生正确的输出——我想到的是“not f(i)”。 - Eli Rose

5
在Python 2.x中,print不是一个函数。在Python 3中,它成为了一个函数。

1

print是在Python2.x中的语句,不是表达式,因此无法在需要表达式的地方使用。

你需要从__future__导入print_function以使其正常工作。

In [105]: from __future__ import print_function

In [107]: [i for i in range(0, 10) if print(i) or True]
0
1
2
3
4
5
6
7
8
9
Out[107]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

请注意,由于print()返回值为None,因此在您的or条件中必须首先放置它,或者使用and条件:if True and not print(i)

这是列表推导式的返回值;print()没有被调用。 - Martijn Pieters
True and print(i) 不会做你想要的事情;它会评估为 False,因此不会将任何内容添加到结果列表中。 - Martijn Pieters
@MartijnPieters 啊!是的,忘记在它之前加上一个“不”。 - Ashwini Chaudhary
or True 版本更通用,因为第一个表达式返回什么并不重要。如果你将 print() 替换为可能返回任何东西的内容,包括真值和假值,or True 确保它总是会返回 True - Martijn Pieters
1
并不是说这个OP应该完全不使用它。 - Martijn Pieters

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