34
def isBig(x):
   if x > 4: 
       return 'apple'
   else: 
       return 'orange'

这有效:

if isBig(y): return isBig(y)

这不起作用:

if fruit = isBig(y): return fruit

为什么第二个不起作用!?我想要一个 1 班轮。除了,第一个将调用函数 TWICE。

如何使其成为 1 班轮,而无需两次调用该函数?

4

7 回答 7

116

开始Python 3.8,并引入赋值表达式 (PEP 572) ( :=operator),现在可以将条件值 ( isBig(y)) 作为变量 ( x) 捕获,以便在条件体中重用它:

if x := isBig(y): return x
于 2019-04-27T15:37:48.073 回答
18

我看到其他人已经指出了我的旧“分配和设置”食谱食谱,它最简单的版本归结为:

class Holder(object):
   def set(self, value):
     self.value = value
     return value
   def get(self):
     return self.value

h = Holder()

...

if h.set(isBig(y)): return h.get()

但是,这主要是为了简化 Python 和在ifor中直接支持赋值的语言之间的音译while。如果您在级联中有“数百个”这样的检查和返回,那么做一些完全不同的事情会更好

hundreds = isBig, isSmall, isJuicy, isBlah, ...

for predicate in hundreds:
  result = predicate(y)
  if result: return result

甚至像

return next(x for x in (f(y) for f in hundreds) if x)

如果没有满足谓词,则可以得到 StopIteration 异常,或者

return next((x for x in (f(y) for f in hundreds) if x)), None)

ifNone是不满足谓词时的正确返回值等。

几乎总是,使用(甚至希望使用;-)Holder技巧/非习语是一种“设计气味”,它建议寻找一种不同的、更 Pythonic 的方法——Holder有理由的一种情况正是我的特殊情况设计它,即您希望在 Python 代码和一些非 Python 代码之间保持密切对应的情况(您正在用 Python 音译参考算法并希望它在将其重构为更 Python 的形式之前首先工作,或者您'将 Python 重新编写为原型,一旦它有效工作,它将被音译为 C++、C#、Java 等)。

于 2009-10-11T17:31:16.687 回答
8

一个衬里不起作用,因为在 Python 中,赋值 ( fruit = isBig(y)) 是一个语句,而不是一个表达式。在 C、C++、Perl 和无数其他语言中,它是一个表达式,你可以把它放在 anif或 awhile或任何你喜欢的地方,但在 Python 中不行,因为 Python 的创建者认为这太容易被误用(或滥用) 来编写“聪明”的代码(就像你正在尝试的那样)。

另外,您的示例相当愚蠢。isBig()将始终评估为true,因为唯一为假的字符串是空字符串 ( ""),因此if在这种情况下您的语句是无用的。我认为这只是对您尝试做的事情的简化。只需这样做:

tmp = isBig(y)
if tmp: return tmp

真的有那么糟糕吗?

于 2009-10-11T08:03:25.283 回答
2

如果您想用 PHP(或 C)编写代码,请在其中编写代码。不要试图将它的方法强加到另一种语言上。

Python 背后的基本原则之一(在我看来)是它的可读性。你应该使用:

fruit = isBig(y)
if fruit: return fruit

我还要提一下,你的使用isXXX()很奇怪;它通常用于返回布尔值。特别是在这种情况下,您在IF语句中使用它。

于 2009-10-11T08:03:19.947 回答
2

您可以使用生成器:

def ensure(x):
    if x: yield x

for fruit in ensure(isBig(y)):
    return fruit
于 2018-04-05T13:54:26.697 回答
0

问题是赋值操作不能被评估为具有布尔值。该if语句依赖于能够评估布尔值。例如,

>>> fruit = 'apple'
>>> bool(fruit = 'apple')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/Users/jem/<ipython console> in <module>()

TypeError: 'fruit' is an invalid keyword argument for this function
>>> bool('a')
True
于 2009-10-11T08:02:37.577 回答
-8
print "apple" if x > 4 else "orange"
于 2013-10-30T16:22:20.393 回答