在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循环条件中分配变量?的主要内容,如果未能解决你的问题,请参考以下文章