跟老齐学Python之关于循环的小伎俩


Posted in Python onOctober 02, 2014

不是说while就不用,比如前面所列举而得那个猜数字游戏,在业务逻辑上,用while就更容易理解(当然是限于那个游戏的业务需要而言)。另外,在某些情况下,for也不是简单地把对象中的元素遍历一遍,比如有有隔一个取一个的要求,等等。

在编写代码的实践中,为了对付循环中的某些要求,需要用一些其它的函数,比如前面已经介绍过的range就是一个被看做循环中的计数器的好东西。

range

在《有容乃大的list(4)》中,专门对range()这个内置函数做了详细介绍,看官可以回到那节教程复习一番。这里重点是复习并展示一下它的for循环中,做为计数器的使用。

还记得曾经在教程中有一个问题:列出100以内被3整除的数。下面引用那个问题的代码和运行结果。

#! /usr/bin/env python

#coding:utf-8
aliquot = []
for n in range(1,100):

    if n%3 == 0:

        aliquot.append(n)
print aliquot

代码运行结果:

[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]

这个问题,如果改写一下(也有网友在博客中提出了改写方法)

>>> aliquot = [ x for x in range(1,100) if x%3==0 ] #用list解析,本质上跟上面无太大差异

>>> aliquot

[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]
>>> aliquot = range(3,100,3)    #这种方法更简单。这是博客中一网友提供。

>>> aliquot

[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]

如果有一个由字母组成的字符串,只想隔一个从字符串中取一个字母。可以这样来实现,这是range()的一个重要用途。

>>> one = "Ilikepython" 

>>> new_list = [ one[i] for i in range(0,len(one),2) ]

>>> new_list

['I', 'i', 'e', 'y', 'h', 'n']

当然,间隔的举例,是可以任意指定的。还是前面那个问题,还可以通过下面的方式,选出所有能够被3整除的数。

>>> all_int = range(1,100)

>>> all_int

[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99]

>>> aliquot = [ all_int[i] for i in range(len(all_int)) if all_int[i]%3==0 ]

>>> aliquot

[3, 6, 9, 12, 15, 18, 21, 24, 27, 30, 33, 36, 39, 42, 45, 48, 51, 54, 57, 60, 63, 66, 69, 72, 75, 78, 81, 84, 87, 90, 93, 96, 99]

通过上述实例,主要是让看官理解range()在for循环中计数器的作用。

zip

在《难以想象的for》中,已经对zip进行了介绍,此处还要提到这个函数,不仅仅是复习,还能深入一下,更主要是它也会常常被用到循环之中。

zip是用于并行遍历的函数。

比如有两个list,元素是由整数组成,如果计算对应位置元素的和。一种方法是通过循环,分别从两个list中取出元素,然后求和。

>>> list1 = range(2,10,2)

>>> list1

[2, 4, 6, 8]

>>> list2 = range(11,20,2)

>>> list2

[11, 13, 15, 17, 19]

>>> result = [ list1[i]+list2[i] for i in range(len(list1)) ]

>>> result

[13, 17, 21, 25]

正如在《for循环语句》中讲述的那样,上面的方法不是很完美,在上一讲中有比较完美一点的代码,请看官欣赏。

zip完成上面的任务,是这么做的:

>>> list1

[2, 4, 6, 8]

>>> list2

[11, 13, 15, 17, 19]

>>> for a,b in zip(list1,list2):

...     print a+b, 

... 

13 17 21 25

zip()的作用就是把list1和list2两个对象中的对应元素放到一个元组(a,b)中,然后对这两个元素进行操作。

>>> list1

[2, 4, 6, 8]

>>> list2

[11, 13, 15, 17, 19]

>>> zip(list1,list2)

[(2, 11), (4, 13), (6, 15), (8, 17)]

对这个功能,看官可以理解为,将两个list压缩成为(zip)一个list,只不过找不到配对的就丢掉了。

能够压缩,也能够解压缩,用下面的方式就是反过来了。

>>> result = zip(list1,list2)

>>> result

[(2, 11), (4, 13), (6, 15), (8, 17)]

>>> zip(*result)

[(2, 4, 6, 8), (11, 13, 15, 17)]

列位注意观察,解压缩得到的结果,跟前面压缩前的结果相比,第二项就少了一个元素19,因为在压缩的时候就丢掉了。

这似乎跟for没有什么关系呀。别着急,思考一个问题,看看如何求解:

问题描述:有一个dictionary,myinfor = {"name":"qiwsir","site":"qiwsir.github.io","lang":"python"},将这个字典变换成:infor = {"qiwsir":"name","qiwsir.github.io":"site","python":"lang"}

解法有几个,如果用for循环,可以这样做(当然,看官如果有方法,欢迎贴出来)。

>>> infor = {}

>>> for k,v in myinfor.items():

...     infor[v]=k

... 

>>> infor

{'python': 'lang', 'qiwsir.github.io': 'site', 'qiwsir': 'name'}

下面用zip()来试试:

>>> dict(zip(myinfor.values(),myinfor.keys()))

{'python': 'lang', 'qiwsir.github.io': 'site', 'qiwsir': 'name'}

呜呼,这是什么情况?原来这个zip()还能这样用。是的,本质上是这么回事情。如果将上面这一行分解开来,看官就明白其中的奥妙了。

>>> myinfor.values()    #得到两个list

['python', 'qiwsir', 'qiwsir.github.io']

>>> myinfor.keys()

['lang', 'name', 'site']

>>> temp = zip(myinfor.values(),myinfor.keys())     #压缩成一个list,每个元素是一个tuple

>>> temp

[('python', 'lang'), ('qiwsir', 'name'), ('qiwsir.github.io', 'site')]
>>> dict(temp)                          #这是函数dict()的功能,将上述列表转化为dictionary

{'python': 'lang', 'qiwsir.github.io': 'site', 'qiwsir': 'name'}

至此,是不是明白zip()和循环的关系了呢?有了它可以让某些循环简化。特别是在用python读取数据库的时候(比如mysql),zip()的作用更会显现。

enumerate

enumerate的详细解释,在《再深点,更懂list》中已经有解释,这里姑且复习。

如果要对一个列表,想得到其中每个元素的偏移量(就是那个脚标)和对应的元素,怎么办呢?可以这样:

>>> mylist = ["qiwsir",703,"python"]

>>> new_list = []

>>> for i in range(len(mylist)):

...     new_list.append((i,mylist[i]))

... 

>>> new_list

[(0, 'qiwsir'), (1, 703), (2, 'python')]

enumerate的作用就是简化上述操作:

>>> enumerate(mylist)

<enumerate object at 0xb74a63c4>    #出现这个结果,用list就能显示内容.类似的会在后面课程出现,意味着可迭代。

>>> list(enumerate(mylist))

[(0, 'qiwsir'), (1, 703), (2, 'python')]

对enumerate()的深刻阐述,还得看这个官方文档:

class enumerate(object)

| enumerate(iterable[, start]) -> iterator for index, value of iterable

|

| Return an enumerate object. iterable must be another object that supports

| iteration. The enumerate object yields pairs containing a count (from

| start, which defaults to zero) and a value yielded by the iterable argument.

| enumerate is useful for obtaining an indexed list:

| (0, seq[0]), (1, seq[1]), (2, seq[2]), ...

|

| Methods defined here:

|

| getattribute(...)

| x.getattribute('name') <==> x.name

|

| iter(...)

| x.iter() <==> iter(x)

|

| next(...)

| x.next() -> the next value, or raise StopIteration
Data and other attributes defined here:

new =

T.new(S, ...) -> a new object with type S, a subtype of T

对官方文档,有的朋友可能看起来有点迷糊,不要紧,至少浏览一下,看个大概。因为随着个人实践的越来越多,对文档的含义理解会越来越深刻。这就好比令狐冲,刚刚学习了独孤九剑的口诀和招式后,理解不是很深刻,只有在不断的打打杀杀实践中,特别跟东方不败等高手过招之后,才能越来越体会到独孤九剑中的奥妙。

Python 相关文章推荐
[原创]pip和pygal的安装实例教程
Dec 07 Python
matplotlib绘制动画代码示例
Jan 02 Python
浅析python打包工具distutils、setuptools
Apr 20 Python
python实现监控某个服务 服务崩溃即发送邮件报告
Jun 21 Python
python3基于TCP实现CS架构文件传输
Jul 28 Python
对numpy中的transpose和swapaxes函数详解
Aug 02 Python
django框架自定义用户表操作示例
Aug 07 Python
python实现两张图片的像素融合
Feb 23 Python
Tensorflow中tf.ConfigProto()的用法详解
Feb 06 Python
TensorFlow tf.nn.softmax_cross_entropy_with_logits的用法
Apr 19 Python
PyQt5 控件字体样式等设置的实现
May 13 Python
浅谈keras中的Merge层(实现层的相加、相减、相乘实例)
May 23 Python
跟老齐学Python之for循环语句
Oct 02 #Python
跟老齐学Python之用while来循环
Oct 02 #Python
跟老齐学Python之复习if语句
Oct 02 #Python
python中pycurl库的用法实例
Sep 30 #Python
python采用getopt解析命令行输入参数实例
Sep 30 #Python
Python实现115网盘自动下载的方法
Sep 30 #Python
python打开网页和暂停实例
Sep 30 #Python
You might like
在 PHP 中使用随机数的三个步骤
2006/10/09 PHP
文件上传之SWFUpload插件(代码)
2015/07/30 PHP
Laravel框架实现即点即改功能的方法分析
2019/10/31 PHP
QQ邮箱的一个文本编辑器代码
2007/03/14 Javascript
js ondocumentready onmouseover onclick onmouseout 样式
2010/07/22 Javascript
jquery ui dialog实现弹窗特效的思路及代码
2013/08/03 Javascript
$.each遍历对象、数组的属性值并进行处理
2014/07/18 Javascript
JavaScript中this详解
2015/09/01 Javascript
JavaScript代码里的判断小结
2016/08/22 Javascript
遍历json 对象的属性并且动态添加属性的实现
2016/12/02 Javascript
js 动态生成html 触发事件传参字符转义的实例
2017/02/14 Javascript
jquery动态添加以及遍历option并获取特定样式名称的option方法
2018/01/29 jQuery
详解js类型判断
2018/05/22 Javascript
js实现多个倒计时并行 js拼团倒计时
2019/02/25 Javascript
Vue 的双向绑定原理与用法揭秘
2020/05/06 Javascript
JavaScript冒泡算法原理与实现方法深入理解
2020/06/04 Javascript
Vue-router中hash模式与history模式的区别详解
2020/12/15 Vue.js
[03:33]TI9战队采访 - Infamous
2019/08/20 DOTA
python 迭代器和iter()函数详解及实例
2017/03/21 Python
简单了解python高阶函数map/reduce
2019/06/28 Python
2014年社区学雷锋活动总结
2014/03/09 职场文书
医师定期考核实施方案
2014/05/07 职场文书
优秀毕业生就业推荐信
2014/05/22 职场文书
假面舞会策划方案
2014/05/29 职场文书
2014高考励志标语
2014/06/05 职场文书
舞蹈专业求职信
2014/06/13 职场文书
没有孩子的离婚协议书怎么写
2014/09/17 职场文书
教师群众路线教育实践活动个人对照检查材料
2014/11/04 职场文书
2014年店长工作总结
2014/11/17 职场文书
财务部岗位职责范本
2015/04/14 职场文书
烈士陵园扫墓感想
2015/08/07 职场文书
信息技术研修心得体会
2016/01/08 职场文书
python实现大文本文件分割成多个小文件
2021/04/20 Python
linux下导入、导出mysql数据库命令的实现方法
2021/05/26 MySQL
5行Python代码实现一键批量扣图
2021/06/29 Python
Python连接Postgres/Mysql/Mongo数据库基本操作大全
2021/06/29 Python