在Python的while循环条件中分配变量?

Posted

技术标签:

【中文标题】在Python的while循环条件中分配变量?【英文标题】:Assign variable in while loop condition in Python? 【发布时间】:2011-10-01 15:32:41 【问题描述】:

我刚刚遇到了这段代码

while 1:
    line = data.readline()
    if not line:
        break
    #...

并想,必须有更好的方法来做到这一点,而不是使用break 的无限循环。

所以我尝试了:

while line = data.readline():
    #...

很明显,出现了错误。

有什么方法可以避免在这种情况下使用break

编辑:

理想情况下,您应该避免说两次readline...恕我直言,重复甚至比break 更糟糕,尤其是在语句很复杂的情况下。

【问题讨论】:

虽然这是一个很好的问题,我认为for line in data 解决方案非常适合这个特定问题,但我认为while True: ... break 成语没有任何问题。不要害怕它。 :-) 这些答案提供了在 while 循环的条件下赋值的替代方法,但实际上并没有回答这个问题:有没有办法在 while 循环中进行赋值?我遇到了同样的问题,试图做 while (character = string[i]): I know for-loop 是迭代字符串的更好方法,但我的条件是实际上比这复杂得多,我想将这个赋值作为条件中“或”的右侧。 @KirkStrauser break 结构的问题在于,它使用四行来表达某些东西,而其他语言只需一行就可以做到。然而,它做正确的事。到目前为止给出的答案都没有提供更好的通用解决方案。它们要么只使用迭代器,要么重复赋值,这比 break 版本的额外三行代码更糟糕。 【参考方案1】:

Python 3.8 开始,并引入assignment expressions (PEP 572)(:= 运算符),现在可以将while 循环的条件值(data.readline())捕获为变量(line),以便在循环体内重复使用它:

while line := data.readline():
  do_smthg(line)

【讨论】:

【参考方案2】:

试试这个,适用于用open('filename')打开的文件

for line in iter(data.readline, b''):

【讨论】:

+1 用于在 python 核心文档中举例说明:docs.python.org/2/library/functions.html#iter【参考方案3】:

如果您没有对数据做任何花哨的事情,比如稍后阅读更多行,那么总会有:

for line in data:
    ... do stuff ...

【讨论】:

我试图通过考虑一种类型的对象data 来玩 Stump The Sushi Eater,它可能支持 .readline() 但不支持 __iter__()。我在画一个空白。你知道任何副手吗? 这不需要先将整个文件读入内存吗?这似乎不适用于大文件。 (特别是如果文件比你的 ram 可以容纳的大!) 如果 data 是一个文件对象(这是一个奇怪的名字,但这是 OP 使用它的方式),那么整个文件将不会被读入内存。 for line in data 将遍历行,根据需要读取它们。 @NedBatchelder:根据docs.python.org/2/library/stdtypes.html#file.next 的文档 - 以及我不幸的经历 - 文件指针不在您期望的位置(例如data.tell())和for line in data 和甚至在读取最后一行之前甚至可能位于文件末尾。因此,如果您指望 python/os 来计算您在文件中的位置,它并不能完全“根据需要读取它们”。 @mpag 绝对不能保证(我也不是暗示有)每一行都根据需要精确读取。我反对将整个文件读入内存的想法。如果按行进行迭代,则无法对文件指针的位置做出任何假设。【参考方案4】:

这并没有好多少,但这是我通常这样做的方式。 Python 不会像其他语言(例如 Java)那样在变量赋值时返回值。

line = data.readline()
while line:
    # ... do stuff ... 
    line = data.readline()

【讨论】:

我不是这个的忠实拥护者,特别是如果... do stuff ... 相当大,因为它要求你在修改它时牢记整个循环的流程。例如,如果您稍后添加 if line.startswith('foo'): continue 之类的内容而没有意识到 line 仅在最后更新,那么您不小心创建了一个无限循环。 @Kirk - 在某种程度上,我同意,但替代方案也好不到哪里去。理想情况下,你使用的类实现了一个生成器,你可以只使用一个 for 循环,但在某些情况下你需要一个 while 循环(例如,'while cur_time>expected_time:')。我不知道 OPs 的帖子是否更好,但我想这是一个见仁见智的问题 :) 经典的while循环,任何水平的程序员都可以理解。可能是未来维护目的的最佳选择。 @Kirk Strauser 有人可能会争辩说,如果 ... do stuff ... 太长了,以至于您忘记了循环中发生的事情,那么您可能做错了。【参考方案5】:

喜欢,

for line in data:
    # ...

?它很大程度上取决于 data 对象的 readline 语义的语义。如果 data 是一个 file 对象,那将起作用。

【讨论】:

【参考方案6】:
for line in data:
    ... process line somehow....

将遍历file 中的每一行,而不是使用while。根据我的经验(在 Python 中),读取文件的任务是一个更常见的习语。

事实上,data 不必是一个文件,而只是提供一个迭代器。

【讨论】:

【参考方案7】:

从 python 3.8(实现 PEP-572)开始,此代码现在有效:

while line := data.readline():
   # do something with line 

【讨论】:

【参考方案8】:

如果data 有一个函数返回一个迭代器而不是readline(比如data.iterate),你可以这样做:

for line in data.iterate():
    #...

【讨论】:

除非你知道 data 很小(甚至那时真的没有),否则不要这样做,因为 .readlines() 将整个内容吸入 RAM,但它并没有真正为你买任何东西返回。 如果函数返回一个迭代器而不是整个列表,它应该可以正常工作,对吗? 是的,但我还没有看到 .readlines() 以这种方式实现。 file.readlines() 的文档说它将“使用 readline() 读取直到 EOF 并返回一个包含如此读取的行的列表。” 我更喜欢这个答案。 :-) 但是,iterate 的常用名称是__iter__,然后您可以将循环重写为for line in data 是的,但我要这样说,因为已经有 4 个其他答案具有 for line in data。 =D【参考方案9】:

如果data 是一个文件,如其他答案所述,使用for line in file 可以正常工作。如果 data 不是文件,并且是随机数据读取对象,那么您应该将其实现为迭代器,实现 __iter__next 方法。

next 方法应该读取,检查是否有更多数据,如果没有,请提出StopIteration。如果这样做,您可以继续使用for line in data 成语。

【讨论】:

【参考方案10】:

根据 Python 文档中的 FAQ,使用 for 构造迭代输入或运行无限 while True 循环并使用 break 语句终止它是首选和惯用的迭代方式。

【讨论】:

【参考方案11】:

你可以这样做:

line = 1
while line:
    line = data.readline()

【讨论】:

这将比预期多执行一次循环体。

以上是关于在Python的while循环条件中分配变量?的主要内容,如果未能解决你的问题,请参考以下文章

While 循环条件在:复合条件表达式 AND'd [python]

第六篇:循环语句 - while和for

在没有numpy的python中分配一个变量NaN

python基础:变量编码运算符条件语句while循环

在 Python 中分配类布尔值

python第七课——循环结构 while