Python 在 while 循环中的条件期间为变量赋值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19767891/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Python Assign value to variable during condition in while Loop
提问by Borut Flis
A simple question about Python syntax. I want to assign a value from a function to a variable during the condition for a while loop. When the value returned from the function is false, the loop should break. I know how to do it in PHP.
关于 Python 语法的一个简单问题。我想在 while 循环的条件期间将一个函数的值分配给一个变量。当函数返回的值为 false 时,循环应该中断。我知道如何在 PHP 中做到这一点。
while (($data = fgetcsv($fh, 1000, ",")) !== FALSE)
However when I try a similar syntax in Python I get a syntax error.
但是,当我在 Python 中尝试类似的语法时,出现语法错误。
采纳答案by Martijn Pieters
You cannot use assignment in an expression. Assignment is itself a statement, and you cannot combine Python statements.
不能在表达式中使用赋值。赋值本身就是一个语句,不能组合 Python 语句。
This is an explicit choice made by the language designers; it is all too easy to accidentally use one =
and assign, where you meant to use two ==
and test for equality.
这是语言设计者做出的明确选择;很容易不小心使用一个=
并分配,而您打算使用两个==
并测试相等性。
Move the assignment intothe loop, or assign beforethe loop, and assign new values in the loop itself.
将赋值移到循环中,或在循环之前赋值,并在循环本身中赋值新值。
For your specific example, the Python csv
modulegives you a higher-level API and you'd be looping over the csv.reader()
instead:
对于您的特定示例,Pythoncsv
模块为您提供了一个更高级别的 API,您将csv.reader()
改为循环:
with open(csvfilename, 'rb') as csvfh:
reader = csv.reader(csvfh)
for row in reader:
I rarely, if ever, need to assign in a loop construct. Usually there is a (much) better way of solving the problem at hand.
我很少(如果有的话)需要在循环结构中进行分配。通常有一种(好得多)更好的方法来解决手头的问题。
That said, as of Python 3.8 the language will actually have assignment expressions, using :=
as the assignment operator. See PEP 572. Assignment expressions are actually useful in list comprehensions, for example, when you need to both include a method return value in the list you are building and need to be able to use that value in a test.
也就是说,从 Python 3.8 开始,该语言实际上将具有赋值表达式,:=
用作赋值运算符。参见PEP 572。赋值表达式在列表推导中实际上很有用,例如,当您需要在正在构建的列表中包含一个方法返回值并且需要能够在测试中使用该值时。
Now, you'd have to use a generator expression:
现在,您必须使用生成器表达式:
absolute = (os.path.abspath(p) for p in files)
filtered = [abs for abs in absolute if included(abs)]
but with assignment expressions you can inline the os.path.abspath()
call:
但是使用赋值表达式,您可以内联os.path.abspath()
调用:
filtered = [abs for p in files if included(abs := os.path.abspath(p))]
回答by RemcoGerlich
2020 answer:
2020 答案:
Since Python 3.8, the "walrus operator" :=exists that does exactly what you want:
从 Python 3.8 开始,“海象运算符” :=存在,它完全符合您的要求:
while data := fgetcsv(fh, 1000, ",") != False:
pass
(if that fgetcsv function existed)
(如果存在 fgetcsv 函数)
2013 answer:You can't do that in Python, no assignment in expressions. At least that means you won't accidentally type == instead of = or the other way around and have it work.
2013 年答案:您不能在 Python 中做到这一点,表达式中没有赋值。至少这意味着您不会意外地键入 == 而不是 = 或其他方式并使其工作。
Traditional Python style is to just use while True and break:
传统的 Python 风格只是使用 while True 和 break:
while True:
data = fgetcsv(fh, 1000, ",")
if not data:
break
# Use data here
But nowadays I'd put that in a generator:
但现在我把它放在一个发电机中:
def data_parts(fh):
while True:
data = fgetcsv(fh, 1000, ",")
if not data:
break
yield data
so that in the code that uses the file, the ugliness is hidden away:
这样在使用该文件的代码中,丑陋就被隐藏了:
for data in data_parts(fh):
# Use data here
Of course if it's actually CSV reading that you're doing, use the csv module.
当然,如果它实际上是您正在执行的 CSV 读取,请使用 csv 模块。
回答by ArtOfWarfare
I wrote a little Python module, which I call let
, which allows you to perform a variable assignment anywhere that a function is allowed.
我编写了一个小的 Python 模块,我称之为let
,它允许您在允许函数的任何地方执行变量赋值。
Install it like this:
像这样安装它:
pip install let
I believe the following will accomplish what you're looking for:
我相信以下将完成您正在寻找的内容:
from let import let
while let(data = fgetcsv(fh, 1000, ',')):
# Do whatever you'd like with data here
However... Duncan's comment the original question saying to use iter
is interesting. I wasn't aware of the function until he brought it up, and I now believe it may be a better solution than mine. It's debatable - iter
requires a sentinel to be explicitly provided, whereas mine doesn't care and simply waits for fgetcsv
to return any False
y value.
但是......邓肯的评论说使用的原始问题iter
很有趣。直到他提出这个功能我才意识到它,现在我相信它可能是比我更好的解决方案。这是有争议的 -iter
需要明确提供一个哨兵,而我的不在乎,只是等待fgetcsv
返回任何False
y 值。