【问题标题】:Can't we do something like if (y = Foo()) > 2: in python? [duplicate]我们不能在 python 中做类似 if (y = Foo()) > 2: 的事情吗? [复制]
【发布时间】:2015-12-15 07:00:33
【问题描述】:

我是 python 新手。 在 C/C++ 中,在 while 或 if 语句中,我经常进行变量赋值。下面是一个简单的C++示例代码:

#include <iostream>

int Increment(const int x) {
  return (x + 1); 
}

int main(void) {
  int x = 2, y;
  while ((y = Increment(x)) > 2) {
    std::cout << "y is larger than 2" << std::endl;
  }

  return (0);
}

但是下面的python代码不起作用:

#!/usr/bin/python

def Increment(x):
  return x + 1

def main():
  x= 2
  while (y = Increment(x)) > 2:
    print "y is larger than 2"

if __name__ == "__main__"
  main()

错误信息如下:

   while (y = Increment(x)) > 2:
          ^
SyntaxError: invalid syntax

似乎在python中,不能在比较语句中进行变量赋值对吧?那么,在 python 中执行此操作的最佳方法是什么?

def main():
x = 2
  y = Increment(x)
  while y > 2:
    print "y is larger than 2"
    y = Increment(x)

【问题讨论】:

  • 我知道您的代码只是示例,但也许下次尝试制作一些不会进入无限循环的示例代码? :)

标签: python conditional-statements variable-assignment


【解决方案1】:

没有办法在 Python 的表达式中分配变量。

但是,由于您的循环永远循环,并且Increment(x) 没有副作用,您可以这样做(行为相同):

def main():
    while True:
        print("y is larger than 2")

【讨论】:

  • 也可以省略x = 2
  • @TimCastelijns 好点:p
【解决方案2】:

Python 和 C(或 C++)的区别在于,在 Python 中赋值是一个语句,而在 C(和 C++)中赋值是一个表达式。 p>

表达式可以是其他表达式的一部分,但语句是独立的。

【讨论】:

    【解决方案3】:

    不,但您可以(必须)绑定到 for 循环中的变量。因此,对于您的示例,请尝试停止使用 C/C++ 思考并开始思考 Python:使用 for 循环并将 while 的条件部分移动到生成器中。

    不幸的是,您的示例实际上并没有做任何有用的事情并且永远循环,但大多数实际示例会很快简化为比while 更简洁的东西。

    对于给出的示例,您甚至不需要生成器,只需将调用迭代到 Increment(x)

    #!/usr/bin/python
    
    def Increment(x):
      return x + 1
    
    def main():
      x= 2
      for y in iter(lambda: Increment(x)):
          if y <= 2: break
          print "y is larger than 2"
    
    if __name__ == "__main__"
      main()
    

    如果函数有一个表示完成的固定返回(例如,None 表示数据结束),那么iter() 的两个参数版本很有用,您不需要单独检查:

    >>> def collatz(x):
        if x%2:
            return 3*x+1
        return x//2
    
    >>> x = 5
    >>> for y in iter(lambda: collatz(x), 1):
        print(y)
        x = y
    
    
    16
    8
    4
    2
    

    生成器版本是:

    >>> def collatz(x):
        while x != 1:
            x = 3*x+1 if x%2 else x//2
            yield x
    
    >>> for y in collatz(7):
        print(y, end=' ')
    
    
    22 11 34 17 52 26 13 40 20 10 5 16 8 4 2 1 
    

    它巧妙地将复杂的循环逻辑与我们想要在每次迭代中执行的操作分开。

    【讨论】:

      【解决方案4】:

      我不会重复调用Increment(),而是这样构建循环:

      x = 2
      while True:
          y = Increment(x);
          if not y > 2:
              break
          print "y is larger than 2"
      

      这也在The Python design FAQ 中进行了讨论,它建议使用相同的代码。

      FAQ 还提到了使用迭代:

      for y in itertools.repeat(Increment(x)):
          if not y > 2:
              break
          print "y is larger than 2"
      

      或者:

      from itertools import takewhile, repeat
      for y in takewhile(lambda y: y > 2, repeat(Increment(x)):
          print "y is larger than 2"
      

      这段代码实际上并不是每次在循环中调用Increment,它依赖于每次都是相同值的知识。但就像在邓肯的回答中一样,您可以例如使用iterlambda 来改变它。如果在循环中修改了x,则需要进行此类操作。以下任何内容都将进行迭代,并且根据实际代码与此示例的不同之处,您可能希望将代码基于其中任何一个。例如,itertools.repeat(x) 可以轻松更改为 itertools.count(x)xrange(x) 或任何其他迭代器,而在 iter(lambda: x) 中,x 可以轻松更改为您喜欢的任何其他表达式。

      itertools.repeat(Increment(x))
      iter(lambda: Increment(x))
      itertools.imap(Increment, itertools.repeat(x))
      itertools.imap(Increment, iter(lambda: x))
      

      然后您可以将itertools.takewhile 应用于其中任何一个。

      【讨论】:

        猜你喜欢
        • 2022-12-17
        • 2020-03-08
        • 1970-01-01
        • 2012-12-17
        • 1970-01-01
        • 2018-11-21
        • 1970-01-01
        • 1970-01-01
        • 2016-11-08
        相关资源
        最近更新 更多