关于Python语法的一个简单问题。 我想在while循环的条件期间将函数的值赋给变量。 当函数返回的值为false时,循环应该中断。 我知道如何在PHP中完成它。
while (($data = fgetcsv($fh, 1000,",")) !== FALSE)
但是,当我在Python中尝试类似的语法时,我得到一个语法错误。
如果Python中的函数fgetcsv返回字符串或False,那么与PHP中的模式完全相同,则for data in iter(lambda: fgetcsv(fh, 1000,","), False):将具有您想要的效果。
@Duncan - 嗯...如果你想要一个更通用的iter,将任何False y值视为哨兵怎么办?
您不能在表达式中使用赋值。赋值本身就是一个语句,你不能组合Python语句。
这是语言设计者的明确选择;很容易意外地使用一个=并分配,你打算使用两个==并测试相等性。
将赋值移动到循环中,或在循环之前分配,并在循环本身中分配新值。
对于您的具体示例,Python csv模块为您提供了更高级别的API,而您将循环遍历csv.reader():
with open(csvfilename, 'rb') as csvfh:
reader = csv.reader(csvfh)
for row in reader:
如果有的话,我很少需要在循环结构中进行分配。通常有一种(更好)解决手头问题的方法。
也就是说,从Python 3.8开始,语言实际上会有赋值表达式,使用:=作为赋值运算符。请参阅PEP 572.分配表达式在列表推导中实际上很有用,例如,当您需要在正在构建的列表中包含方法返回值并且需要能够在测试中使用该值时。
现在,您必须使用生成器表达式:
absolute = (os.path.abspath(p) for p in files)
filtered = [abs for abs in absolute if included(abs)]
但是使用赋值表达式可以内联os.path.abspath()调用:
filtered = [abs for p in files if included(abs := os.path.abspath(p))]
谢谢。 我实际上需要这个而不是csv,抱歉,如果我感到困惑。
@BorutFlis:当然,但请再次确保检查实现这一目标的更好方法。
只是学习Python并喜欢它的简洁性。 这是让我心烦意乱的第一件事,尽管我能理解语言设计师做出的选择......
@opncow:实际上,Python 3.8将有一个赋值表达式。 见PEP 572。
你不能在Python中做到这一点,在表达式中没有赋值。至少这意味着你不会意外地键入==而不是=或反过来并让它工作。
传统的Python风格只是在True和break时使用:
while True:
data = fgetcsv(fh, 1000,",")
if not data:
break
# Use data here
但是现在我把它放在一台发电机里:
def data_parts(fh):
while True:
data = fgetcsv(fh, 1000,",")
if not data:
break
yield data
所以在使用该文件的代码中,丑陋隐藏起来:
for data in data_parts(fh):
# Use data here
当然,如果它实际上是您正在进行的CSV读取,请使用csv模块。
谢谢。 我将使用不定式循环。
@RemcoGerlich一个简单的生成器而不是while循环的很好的例子。
我写了一个Python模块,我称之为let,它允许您在允许函数的任何地方执行变量赋值。
像这样安装:
pip install let
我相信以下内容将实现您的目标:
from let import let
while let(data = fgetcsv(fh, 1000, ',')):
# Do whatever you'd like with data here
但是...... Duncan评论说使用iter的原始问题很有意思。直到他提起这个功能我才意识到这个功能,我现在相信它可能比我的解决方案更好。这是值得商榷的 - iter要求明确提供标记,而我不关心并且只是等待fgetcsv返回任何False y值。