难以想象的for

看这个标题,有点匪夷所思吗?为什么for是难以想象的呢?因为在python中,它的确是很常用而且很强悍,强悍到以至于另外一个被称之为迭代的东西,在python中就有点相形见绌了。在别的语言中,for的地位从来没有如同python中这么高的。

废话少说,上干活。

for的基本操作

for是用来循环的,是从某个对象那里依次将元素读取出来。看下面的例子,将已经学习过的数据对象用for循环一下,看看哪些能够使用,哪些不能使用。同时也是复习一下过往的内容。

  1. >>> name_str = "qiwsir"
  2. >>> for i in name_str: #可以对str使用for循环
  3. ... print i,
  4. ...
  5. q i w s i r
  6. >>> name_list = list(name_str)
  7. >>> name_list
  8. ['q', 'i', 'w', 's', 'i', 'r']
  9. >>> for i in name_list: #对list也能用
  10. ... print i,
  11. ...
  12. q i w s i r
  13. >>> name_set = set(name_str) #set还可以用
  14. >>> name_set
  15. set(['q', 'i', 's', 'r', 'w'])
  16. >>> for i in name_set:
  17. ... print i,
  18. ...
  19. q i s r w
  20. >>> name_tuple = tuple(name_str)
  21. >>> name_tuple
  22. ('q', 'i', 'w', 's', 'i', 'r')
  23. >>> for i in name_tuple: #tuple也能呀
  24. ... print i,
  25. ...
  26. q i w s i r
  27. >>> name_dict={"name":"qiwsir","lang":"python","website":"qiwsir.github.io"}
  28. >>> for i in name_dict: #dict也不例外
  29. ... print i,"-->",name_dict[i]
  30. ...
  31. lang --> python
  32. website --> qiwsir.github.io
  33. name --> qiwsir

除了上面的数据类型之外,对文件也能够用for,这在前面有专门的《不要红头文件》两篇文章讲解有关如何用for来读取文件对象的内容。看官若忘记了,可去浏览。

for在list解析中,用途也不可小觑,这在讲解list解析的时候,也已说明,不过,还是再复习一下为好,所谓学而时常复习之,不亦哈哈乎。

  1. >>> one = range(1,9)
  2. >>> one
  3. [1, 2, 3, 4, 5, 6, 7, 8]
  4. >>> [ x for x in one if x%2==0 ]
  5. [2, 4, 6, 8]

什么也不说了,list解析的强悍,在以后的学习中会越来越体会到的,佩服佩服呀。

列位如果用python3,会发现字典解析、元组解析也是奇妙的呀。

要上升一个档次,就得进行概括。将上面所说的for循环,概括一下,就是下图所示:

难以想象的for - 图1

用一个文字表述:

  1. for iterating_var in sequence:
  2. statements

iterating_var是对象sequence的迭代变量,也就是sequence必须是一个能够有某种序列的对象,特别注意没某种序列,就是说能够按照一定的脚标获取元素。当然,文件对象属于序列,我们没有用脚标去获取每行,如果把它读取出来,因为也是一个str,所以依然可以用脚标读取其内容。

zip

zip是什么东西?在交互模式下用help(zip),得到官方文档是:

zip(…)
zip(seq1 [, seq2 […]]) -> [(seq1[0], seq2[0] …), (…)]

Return a list of tuples, where each tuple contains the i-th element from each of the argument sequences. The returned list is truncated in length to the length of the shortest argument sequence.

通过实验来理解上面的文档:

  1. >>> a = "qiwsir"
  2. >>> b = "github"
  3. >>> zip(a,b)
  4. [('q', 'g'), ('i', 'i'), ('w', 't'), ('s', 'h'), ('i', 'u'), ('r', 'b')]
  5. >>> c = [1,2,3]
  6. >>> d = [9,8,7,6]
  7. >>> zip(c,d)
  8. [(1, 9), (2, 8), (3, 7)]
  9. >>> e = (1,2,3)
  10. >>> f = (9,8)
  11. >>> zip(e,f)
  12. [(1, 9), (2, 8)]
  13. >>> m = {"name","lang"}
  14. >>> n = {"qiwsir","python"}
  15. >>> zip(m,n)
  16. [('lang', 'python'), ('name', 'qiwsir')]
  17. >>> s = {"name":"qiwsir"}
  18. >>> t = {"lang":"python"}
  19. >>> zip(s,t)
  20. [('name', 'lang')]

zip是一个内置函数,它的参数必须是某种序列数据类型,如果是字典,那么键视为序列。然后将序列对应的元素依次组成元组,做为一个list的元素。

下面是比较特殊的情况,参数是一个序列数据的时候,生成的结果样子:

  1. >>> a
  2. 'qiwsir'
  3. >>> c
  4. [1, 2, 3]
  5. >>> zip(c)
  6. [(1,), (2,), (3,)]
  7. >>> zip(a)
  8. [('q',), ('i',), ('w',), ('s',), ('i',), ('r',)]

这个函数和for连用,就是实现了:

  1. >>> c
  2. [1, 2, 3]
  3. >>> d
  4. [9, 8, 7, 6]
  5. >>> for x,y in zip(c,d): #实现一对一对地打印
  6. ... print x,y
  7. ...
  8. 1 9
  9. 2 8
  10. 3 7
  11. >>> for x,y in zip(c,d): #把两个list中的对应量上下相加。
  12. ... print x+y
  13. ...
  14. 10
  15. 10
  16. 10

上面这个相加的功能,如果不用zip,还可以这么写:

  1. >>> length = len(c) if len(c)<len(d) else len(d) #判断c,d的长度,将短的长度拿出来
  2. >>> for i in range(length):
  3. ... print c[i]+d[i]
  4. ...
  5. 10
  6. 10
  7. 10

以上两种写法那个更好呢?前者?后者?哈哈。我看差不多了。还可以这么做呢:

  1. >>> [ x+y for x,y in zip(c,d) ]
  2. [10, 10, 10]

前面多次说了,list解析强悍呀。当然,还可以这样的:

  1. >>> [ c[i]+d[i] for i in range(length) ]
  2. [10, 10, 10]

for循环语句在后面还会经常用到,其实前面已经用了很多了。所以,看官应该不感到太陌生。