zl程序教程

您现在的位置是:首页 >  后端

当前栏目

Python中for循环详解

Python循环 详解 for
2023-06-13 09:15:16 时间

与其它大多数语言一样,Python也拥有for循环。你到现在还未曾看到它们的唯一原因就是,Python在其它太多的方面表现出色,通常你不需要它们。

其它大多数语言没有像Python一样的强大的list数据类型,所以你需要亲自做很多事情,指定开始,结束和步长,来定义一定范围的整数或字符或其它可重复的实体。但是在Python中,for循环简单地在一个列表上循环,与list解析的工作方式相同。

1.for 循环介绍

复制代码代码如下:


>>>li=["a","b","e"]
>>>forsinli:        (1)
...    prints         (2)
a

e
>>>print"\n".join(li) (3)
a

e

(1) for循环的语法同list解析相似。li是一个list,而s将从第一个元素开始依次接收每个元素的值。
(2) 像if语句或其它任意缩进块,for循环可以包含任意数目的代码行。
(3) 这就是你以前没看到过for循环的原因:至今我们都不需要它。太令人吃惊了,当你想要的只是一个join或是list解析时,在其它语言中常常需要使用for循环。

要做一个“通常的”(VisualBasic标准的)计数for循环也非常简单。

2.简单计数

复制代码代码如下:


>>>foriinrange(5):            (1)
...    printi
0
1
2
3
4
>>>li=["a","b","c","d","e"]
>>>foriinrange(len(li)):      (2)
-104-DiveIntoPythonhttp://diveintopython.org/
...    printli[i]
a

c
d
e

(1) range生成一个整数的list,通过它来控制循环。我知道它看上去有些奇怪,但是它对计数循环偶尔(我只是说偶尔)会有用。
(2) 我们从来没这么用过。这是VisualBasic的思维风格。摆脱它吧。正确遍历list的方法是前面的例子所展示的。

for循环不仅仅用于简单计数。它们可以遍历任何类型的东西。下面的例子是一个用for循环遍历dictionary的例子。

3.遍历 dictionary

复制代码代码如下:
>>>importos
>>>fork,vinos.environ.items():     (1)(2)
...    print"%s=%s"%(k,v)
USERPROFILE=C:\DocumentsandSettings\mpilgrim
OS=Windows_NT
COMPUTERNAME=MPILGRIM
USERNAME=mpilgrim
[...略...]
>>>print"\n".join(["%s=%s"%(k,v)
...    fork,vinos.environ.items()])(3)
USERPROFILE=C:\DocumentsandSettings\mpilgrim
OS=Windows_NT
COMPUTERNAME=MPILGRIM
USERNAME=mpilgrim
[...略...]

(1) os.environ是在你的系统上所定义的环境变量的dictionary。在Windows下,这些变量是可以从MS-DOS访问的用户和系统变量。在UNIX下,它们是在你的shell启动脚本中所export(输出)的变量。在MacOS中,没有环境变量的概念,所以这个dictionary为空。
(2) os.environ.items()返回一个tuple的list:[(key1,value1),(key2,value2),...]。for循环对这个list进行遍历。第一轮,它将key1赋给k,value1赋给v,所以k=USERPROFILE,v=C:\DocumentsandSettings\mpilgrim。第二轮,k得到第二个键字OS,v得到相应的值Windows_NT。
(3) 使用多变量赋值和list解析,你可以使用单行语句来替换整个for循环。在实际的编码中是否这样做只是个人风格问题;我喜欢它是因为,将一个dictionary映射到一个list,然后将list合并成一个字符串,这一过程显得很清晰。其它的程序员宁愿将其写成一个for循环。请注意在两种情况下输出是一样的,然而这一版本稍微快一些,因为它只有一条print语句而不是许多。

现在我们来看看在第5章介绍的样例程序fileinfo.py中MP3FileInfo的for循环。

复制代码代码如下:
   tagDataMap={"title"  :( 3, 33,stripnulls),
                 "artist" :(33, 63,stripnulls),
                 "album"  :(63, 93,stripnulls),
                 "year"   :(93, 97,stripnulls),
                 "comment":(97,126,stripnulls),
                 "genre"  :(127,128,ord)}                              (1)
   .
   .
   .
           iftagdata[:3]=="TAG":
               fortag,(start,end,parseFunc)inself.tagDataMap.items():(2)
                   self[tag]=parseFunc(tagdata[start:end])               (3)

(1) tagDataMap是一个类属性,它定义了我们正在一个MP3文件中搜索的标记。标记存储为定长字段,只要我们读出文件最后128个字节,那么第3到32字节总是歌曲的名字,33-62总是歌手的名字,63-92为专辑的名字,等等。请注意tagDataMap是一个tuple的dictionary,每个tuple包含两个整数和一个函数引用。
(2) 这个看上去复杂一些,但其实并非如此。这里的for变量结构与items所返回的list的元素的结构相匹配。记住,items返回一个形如(key,value)的tuple的list。list第一个元素是("title",(3,33,<functionstripnulls>)),所以循环的第一轮,tag为"title",start为3,end为33,parseFunc为函数stripnulls。
(3) 现在我们已经从一个单个的MP3标记中提取出了所有的参数,将标记数据保存起来挺容易。我们从start到end对tagdata进行分片,从而得到这个标记的实际数据,调用parseFunc对数据进行后续的处理,接着将
parseFunc的返回值作为值赋值给伪字典self中的键字tag。在遍历完tagDataMap中所有元素之后,self拥有了所有标记的值,你知道看上去是什么样。