Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1792741
  • 博文数量: 335
  • 博客积分: 4690
  • 博客等级: 上校
  • 技术积分: 4341
  • 用 户 组: 普通用户
  • 注册时间: 2010-05-08 21:38
个人简介

无聊之人--除了技术,还是技术,你懂得

文章分类

全部博文(335)

文章存档

2016年(29)

2015年(18)

2014年(7)

2013年(86)

2012年(90)

2011年(105)

分类: Python/Ruby

2011-08-11 20:18:08

6.3. Iterating with for Loops

含有for循环的迭代

Like most other languages, Python has for loops. The only reason you haven't seen them until now is that Python is good at so many other things that you don't need them as often.

如同其它语言一样,Python也有for循环。至今你都没有看大他们的唯一原因就是Python有如此多的优点,以至于你不经常使用它们。

Most other languages don't have a powerful list datatype like Python, so you end up doing a lot of manual work, specifying a start, end, and step to define a range of integers or characters or other iteratable entities. But in Python, a for loop simply iterates over a list, the same way list comprehensions work.

许多语言没有像Python一样,拥有强大的列表数据类型,因此你最后不得不自己手工做许多事,特别是使用开始,结束,然后定义一个步长来定义一系列的整数或是字符或是可迭代的实体区间。但是在Python中,一个for循环简单的迭代一个列表,列表的综合操作也能实现同样的工作。

Example 6.8. Introducing the for Loop

6.8 for循环简介

  1. >>> li = ['a', 'b', 'e']
  2. >>> for s in li: 
  3. ... print s 
  4. a
  5. b
  6. e
  7. >>> print "\n".join(li) 
  8. a
  9. b
  10. e

The syntax for a for loop is similar to list comprehensions. li is a list, and s will take the value of each element in turn, starting from the first element.

for循环的语法很类似于列表复合操作。Li是一个列表,s遍历每一个元素的值,从第一个元素的值开始。

Like an if statement or any other indented block, a for loop can have any number of lines of code in it

.if语句或是其它语句的缩进块一样,一个for循环内可以包含任意行代码。

This is the reason you haven't seen the for loop yet: you haven't needed it yet. It's amazing how often you use for loops in other languages when all you really want is ajoin or a list comprehension.

这就是你迄今都没有看到for循环的原因;你跟本不需要它。当你非常想进行连接或是列表复合操作时,你在其它语言中使用for循环的频率是非常惊人的。

Doing a “normal” (by Visual Basic standards) counter for loop is also simple.

操作一个通常(使用VB的标准)的计数对for循环来时是很简单的。

Example 6.9. Simple Counters

6.9 简单计数

  1. >>> for i in range(5): 
  2. ... print i
  3. 0
  4. 1
  5. 2
  6. 3
  7. 4
  8. >>> li = ['a', 'b', 'c', 'd', 'e']
  9. >>> for i in range(len(li)): 
  10. ... print li[i]
  11. a
  12. b
  13. c
  14. d
  15. e

As you saw in Example 3.20, “Assigning Consecutive Values”, range produces a list of integers, which you then loop through. I know it looks a bit odd, but it is occasionally (and I stress occasionally) useful to have a counter loop.

正如你在例3.20 给变量赋连续值看到的那样,range产生了一个整数列表,也即你循环的列表。我知道尽管它看起来有点奇怪,但是间或非常有用(我强调是间或)进行计数循环。

Don't ever do this. This is Visual Basic-style thinking. Break out of it. Just iterate through the list, as shown in the previous example.

不要尝试这样做。这是VB的思考模式。摆脱这种思维模式。仅仅对列表进行迭代,正如先前的例子所示。

for loops are not just for simple counters. They can iterate through all kinds of things. Here is an example of using a for loop to iterate through a dictionary.

For循环不仅适用于简单的计数循环。它可以对任何类型进行迭代。下面的例子是使用for循环对字典进行迭代。

Example 6.10. Iterating Through a Dictionary

6.10 迭代字典

  1. >>> import os
  2. >>> for k, v in os.environ.items(): 
  3. ... print "%s=%s" % (k, v)
  4. USERPROFILE=C:\Documents and Settings\mpilgrim
  5. OS=Windows_NT
  6. COMPUTERNAME=MPILGRIM
  7. USERNAME=mpilgrim
  8.  
  9. [...snip...]
  10. >>> print "\n".join(["%s=%s" % (k, v)
  11. ... for k, v in os.environ.items()])
  12. USERPROFILE=C:\Documents and Settings\mpilgrim
  13. OS=Windows_NT
  14. COMPUTERNAME=MPILGRIM
  15. USERNAME=mpilgrim
  16.  
  17. [...snip...]

os.environ is a dictionary of the environment variables defined on your system. In Windows, these are your user and system variables accessible from MS-DOS. InUNIX, they are the variables exported in your shell's startup scripts. In Mac OS, there is no concept of environment variables, so this dictionary is empty.

Os.environ是定义在你系统上面环境变量的字典。在windows,这些都是从Ms-dos中可以访问的用户和系统变量。在Unix中,他们是从启动脚本中导入的变量。在Mac OS,没有所谓环境变量的概念,所以该字典为空。

os.environ.items() returns a list of tuples: [(key1value1), (key2value2), ...]. The for loop iterates through this list. The first round, it assigns key1 to k and value1 to v, so k = USERPROFILE and v = C:\Documents and Settings\mpilgrim. In the second round, k gets the second key, OS, and v gets the corresponding value, Windows_NT.

os.environ.item() 返回一个不变数组的列表:[(key1,value1), (key2,value2), (key3,value3)….].for循环遍历整个列表。第一次遍历时,将key1 赋值给变量K,将vlaue1赋值变量v,因此 k的值为USERPROFILE 以及 v 的值为 C:\Documents and Settings\mpilgrim。在第二次循环时,K得到了第二个键值OS V得到了相应的值,WindowsNT

With multi-variable assignment and list comprehensions, you can replace the entire for loop with a single statement. Whether you actually do this in real code is a matter of personal coding style. I like it because it makes it clear that what I'm doing is mapping a dictionary into a list, then joining the list into a single string. Other programmers prefer to write this out as a for loop. The output is the same in either case, although this version is slightly faster, because there is only one printstatement instead of many.

通过使用多个变量一次赋值以及列表复合操作,你可以使用一个简单的语句来替代for循环。在实际的代码中你是否使用这种简单语句只是个人的一种编程爱好。我喜欢它是因为简单语句的方式看起来很是清晰:我所做的就是将一个字典映射成一个列表,接着将列表连接成一个字符串。其它的编程人员更喜欢使用for循环的这种方式。在整个例子中,结果是一样的,尽管简单语句的版本略为快些,这是因为你只需要一个打印语句,而不是需要更多的语句。

Now we can look at the for loop in MP3FileInfo, from the sample fileinfo.py program introduced in Chapter 5.

现在我们看看 第五章fileinfo.py程序中的MP3FileInfo中的for循环语句。

Example 6.11. for Loop in MP3FileInfo

6.11 MP3fileInfo中的For循环

   

  1. tagDataMap = {"title" : ( 3, 33, stripnulls),
  2.                   "artist" : ( 33, 63, stripnulls),
  3.                   "album" : ( 63, 93, stripnulls),
  4.                   "year" : ( 93, 97, stripnulls),
  5.                   "comment" : ( 97, 126, stripnulls),
  6.                   "genre" : (127, 128, ord)} 
  7.     .
  8.     .
  9.     .
  10.             if tagdata[:3] == "TAG":
  11.                 for tag, (start, end, parseFunc) in self.tagDataMap.items():
  12.                     self[tag] = parseFunc(tagdata[start:end])

   

tagDataMap is a class attribute that defines the tags you're looking for in an MP3 file. Tags are stored in fixed-length fields. Once you read the last 128 bytes of the file, bytes 3 through 32 of those are always the song title, 33 through 62 are always the artist name, 63 through 92 are the album name, and so forth. Note that tagDataMap is a dictionary of tuples, and each tuple contains two integers and a function reference.

TagDataMap是一个类属性,它定义了你正在MP3文件中寻找的tagsTags使用固定字段存储。一旦你读取了最后文件的128个字节,从第三个字节到第32个字节通常是歌曲的标题,第33个字节到第62个字节通常是艺术家的名字,第63个字节到92个字节是专辑名字,以及等等。请注意 tagDataMap是一个不变数组类型的列表,每一个不变数组都包含了两个整数和一个函数引用。

This looks complicated, but it's not. The structure of the for variables matches the structure of the elements of the list returned by items. Remember that items returns a list of tuples of the form (keyvalue). The first element of that list is ("title", (3, 33, )), so the first time around the loop, tag gets "title", startgets 3, end gets 33, and parseFunc gets the function stripnulls.

这看起来非常复杂,但是实际是不是。For语句的结构变量用来匹配列表返回的元素结构。你的记住不变数组的列表所返回的项的形式(key,value)。列表的第一个元素时(“title”,”3,33,),因此第一次遍历的时候,tag变量得到”title”,startget 3end 的值为33,,parseFunc获得函数stripnulls.

Now that you've extracted all the parameters for a single MP3 tag, saving the tag data is easy. You slice tagdata from start to end to get the actual data for this tag, callparseFunc to post-process the data, and assign this as the value for the key tag in the pseudo-dictionary self. After iterating through all the elements in tagDataMap, selfhas the values for all the tags, and you know what that looks like.

现在你抽取了所有的针对单一MP3标签的参数,保存tag中的数据是很有容易的。你将tagdata进行切片,从开始到结束,这样就得到了实际tag的数据,callparseFunc传递给post-process数据,然后在伪字典中将改值作为键tag的值。当对所有的元素进行迭代后,tagDataMap本身包含了所有的tag值,正如你所看到的那样。

阅读(820) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~