Python基础的while循环

1 投票
4 回答
559 浏览
提问于 2025-04-15 19:29

我有一个关于Python的新手问题。我有一段代码,感觉写得不够“Python风格”:

    rowindex = 0
    while params.getfirst('myfield'+rowindex):
        myid = params.getfirst('myfield'+rowindex)
        # do stuff with myid
        rowindex+=1

这个脚本的输入是一个HTML页面,里面可以有任意数量的输入框,名字都是“myfield#”,其中#从0开始,依次增加。在Perl语言中,我会这样写:

    rowindex = 0
    while myid =  params.getfirst('myfield'+rowindex):
        #do stuff with myid
        rowindex+=1

但在Python中,这样写是不合法的语法。我知道我现在的写法可以工作,但有没有更好的方法呢?谢谢。

4 个回答

1

你可以这样做。我觉得这样更“灵活”,因为我可以在while循环里面设置任何我想要的条件,而且可以设置很多条件。不过,有些人可能会说这只是个人喜好。

rowindex = 0
while 1:
    myid = params.getfirst('myfield'+rowindex)
    if not myid:  #or check for length of 0 , etc, then break
       break
    rowindex+=1
2

我觉得可以做一个小的生成器,把循环的逻辑封装起来:

import itertools

def genit(params):
  for rowindex in itertools.count():
    theid = params.getfirst('myfield%s' % rowindex)
    if not theid: break
    yield theid

这样一来,应用程序的逻辑(也就是“业务”逻辑)在主流程中就能更清晰地呈现出来:

for myid in genit(params):
    dosomething_with(myid)

特别是如果 dosomething_with 是内联的。生成器真的很棒,可以干净利落地把复杂的循环逻辑和应用程序逻辑分开。

如果出于某种特殊原因,我想在这个特定情况下把它们合并在一起,我还是会避免使用低抽象的 rowindex = 0 / while / rowindex += 1 这种写法,而更倾向于使用 for rowindex in itertools.count():,我觉得这样更清晰、更简洁。这种整体的框架也让你在需要的时候更容易在限制循环和无限循环之间切换,比如在接受的答案中提到的那样,只需把 itertools.count() 改成 xrange(N) 就可以了。

5

一个简单计数器的“无限制”特性听起来很吸引人。但是,这也给了某些人机会去进行一种叫做拒绝服务攻击的恶意行为,他们可能会伪造一个表单,里面有数十亿个字段。你要是试图处理这些数十亿个字段,光是数一数就可能让你的网络服务器瘫痪。

因为Python会自动把数字转换成长整型,所以通常情况下会出现的20亿整数溢出问题在这里不适用。有人可能会用数十亿个字段来严重影响你的网站。

for i in range(1024): # some sensible upper limit, beyond which the input is suspicious
    myid= params.getfirst("myfield%d" % i)
    if not myid: break
        # do stuff with myid

撰写回答