简体   繁体   English

如何在 IF 条件下分配一个变量,然后返回它?

[英]How to assign a variable in an IF condition, and then return it?

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

This works:这有效:

if isBig(y): return isBig(y)

This does NOT work:这不起作用:

if fruit = isBig(y): return fruit

Why doesn't the 2nd one work?.为什么第二个不起作用? I want a 1-liner, Except.我想要一个 1-liner,Except。 the 1st one will call the function TWICE.第一个将两次拨打 function。

How to make it 1 liner, without calling the function twice?如何在不调用 function 两次的情况下使其成为 1 个班轮?

Python 3.8开始,并引入赋值表达式 (PEP 572):=运算符),现在可以将条件值( isBig(y) )捕获为变量( x )以便在正文中重新使用它条件:

if x := isBig(y): return x

I see somebody else has already pointed to my old "assign and set" Cookbook recipe, which boils down in its simplest version to:我看到其他人已经指出了我旧的“分配和设置”食谱食谱,它最简单的版本归结为:

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()

However, this was intended mostly to ease transliteration between Python and languages where assignment is directly supported in if or while .然而,这主要是为了简化 Python 和直接支持ifwhile赋值的语言之间的音译。 If you have "hundreds" of such check-and-return in a cascade, it's much better to do something completely different:如果您在级联中有“数百个”这样的检查和返回,那么做一些完全不同的事情会好得多:

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

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

or even something like甚至像

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

if it's OK to get a StopIteration exception if no predicate is satisfied, or如果不满足谓词,则可以获取 StopIteration 异常,或者

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

if None is the proper return value when no predicate is satisfied, etc.如果None满足谓词时None是正确的返回值,等等。

Almost invariably, using (or even wishing for;-) the Holder trick/non-idiom is a "design smell" which suggests looking for a different and more Pythonic approach -- the one case where Holder is justified is exactly the special case for which I designed it, ie, the case where you want to keep close correspondence between the Python code and some non-Python (you're transliterating a reference algorithm in Python and want it working first before refactoring it into a more Pythonic form, or you're writing Python as a prototype that will be transliterated into C++, C#, Java, etc, once it's working effectively).几乎无一例外,使用(甚至希望为;-)的Holder伎俩/非成语是“设计异味”这表明寻找一个不同的,更Python的方法-其中一个案例Holder是合理的正是对于特殊情况这是我设计的,即,您希望在 Python 代码和某些非 Python 代码之间保持密切对应的情况(您在 Python 中音译一个参考算法,并希望它在将其重构为更 Pythonic 的形式之前首先工作,或者您正在编写 Python 作为原型,一旦它有效工作,它将被音译为 C++、C#、Java 等)。

The one liner doesn't work because, in Python, assignment ( fruit = isBig(y) ) is a statement, not an expression. one liner 不起作用,因为在 Python 中,赋值( fruit = isBig(y) )是一个语句,而不是一个表达式。 In C, C++, Perl, and countless other languages it is an expression, and you can put it in an if or a while or whatever you like, but not in Python, because the creators of Python thought that this was too easily misused (or abused) to write "clever" code (like you're trying to).在 C、C++、Perl 和无数其他语言中,它是一个表达式,你可以把它放在if或 a while或任何你喜欢的地方,但在 Python 中不行,因为 Python 的创造者认为这太容易被误用了(或滥用)编写“聪明”的代码(就像你想的那样)。

Also, your example is rather silly.另外,你的例子很愚蠢。 isBig() will always evaluate to true , since the only string that's false is the empty string ( "" ), so your if statement is useless in this case. isBig()将始终评估为true ,因为唯一为 false 的字符串是空字符串 ( "" ),因此您的if语句在这种情况下是无用的。 I assume that's just a simplification of what you're trying to do.我认为这只是您尝试做的事情的简化。 Just do this:只需这样做:

tmp = isBig(y)
if tmp: return tmp

Is it really that much worse?真的有那么糟糕吗?

If you want to code in PHP (or C), code in it.如果您想用 PHP(或 C)编写代码,请在其中编写代码。 Don't try to force its methods onto another language.不要试图将其方法强加到另一种语言上。

One of the basic tenets behind Python (in my opinion) is its readability. Python 背后的基本原则之一(在我看来)是它的可读性。 You should be using:你应该使用:

fruit = isBig(y)
if fruit: return fruit

I should also mention that your use of isXXX() is very strange;我还应该提到你对isXXX()使用很奇怪; it's usually used to return boolean values.它通常用于返回布尔值。 Especially in this case where you're using it in an IF statement.特别是在这种情况下,您在IF语句中使用它。

You could use a generator:您可以使用生成器:

def ensure(x):
    if x: yield x

for fruit in ensure(isBig(y)):
    return fruit

由于故意的语言设计,此方法不起作用,但是您可以使用此技巧来绕开此决定

The problem is that the assignment operation cannot be evaluated as having a boolean value.问题是赋值操作不能被评估为具有布尔值。 The if statement relies on being able to evaluate a boolean. if语句依赖于能够评估布尔值。 For example,例如,

>>> 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
print "apple" if x > 4 else "orange"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM