跟老齐学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 相关文章推荐
paramiko模块安装和使用(远程登录服务器)
Jan 27 Python
Python最长公共子串算法实例
Mar 07 Python
用Python制作简单的朴素基数估计器的教程
Apr 01 Python
python selenium UI自动化解决验证码的4种方法
Jan 05 Python
怎么使用pipenv管理你的python项目
Mar 12 Python
python如何定义带参数的装饰器
Mar 20 Python
致Python初学者 Anaconda入门使用指南完整版
Apr 05 Python
Python实现字典排序、按照list中字典的某个key排序的方法示例
Dec 18 Python
使用Python和Scribus创建一个RGB立方体的方法
Jul 17 Python
python网络编程之多线程同时接受和发送
Sep 03 Python
python主线程与子线程的结束顺序实例解析
Dec 17 Python
Python实现Word文档转换Markdown的示例
Dec 22 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缓存类代码(附详细说明)
2011/06/09 PHP
php中curl、fsocket、file_get_content三个函数的使用比较
2014/05/09 PHP
php实现短信发送代码
2015/07/05 PHP
PHP版本的选择5.2.17 5.3.27 5.3.28 5.4 5.5兼容性问题分析
2016/04/04 PHP
PHP版单点登陆实现方案的实例
2016/11/17 PHP
PHP preg_match实现正则表达式匹配功能【输出是否匹配及匹配值】
2017/07/19 PHP
JavaScript接口实现代码 (Interfaces In JavaScript)
2010/06/11 Javascript
使用jquery+CSS实现控制打印样式
2014/12/31 Javascript
JavaScript构造函数详解
2015/12/27 Javascript
实现微信小程序的wxml文件和wxss文件在webstrom的支持
2017/06/12 Javascript
javaScript中的空值和假值
2017/12/18 Javascript
Node.js学习之内置模块fs用法示例
2020/01/22 Javascript
js中switch语句的学习笔记
2020/03/25 Javascript
微信小程序实现自定义底部导航
2020/11/18 Javascript
布同 统计英文单词的个数的python代码
2011/03/13 Python
在Python中利用Into包整洁地进行数据迁移的教程
2015/03/30 Python
Python的Django框架使用入门指引
2015/04/15 Python
python开发之thread线程基础实例入门
2015/11/11 Python
Python2.7简单连接与操作MySQL的方法
2016/04/27 Python
磁盘垃圾文件清理器python代码实现
2020/08/24 Python
python url 参数修改方法
2018/12/26 Python
Python标准库使用OrderedDict类的实例讲解
2019/02/14 Python
python3安装crypto出错及解决方法
2019/07/30 Python
python bluetooth蓝牙信息获取蓝牙设备类型的方法
2019/11/29 Python
如何使用Python发送HTML格式的邮件
2020/02/11 Python
Python CSS选择器爬取京东网商品信息过程解析
2020/06/01 Python
Python生成并下载文件后端代码实例
2020/08/31 Python
Python logging日志库空间不足问题解决
2020/09/14 Python
IE矩阵Matrix滤镜旋转与缩放及如何结合transform
2012/11/29 HTML / CSS
心碎乌托邦的创业计划书范文
2013/12/26 职场文书
我未来的职业规划范文
2014/01/11 职场文书
会计求职信
2014/05/29 职场文书
社团活动总结书
2014/06/27 职场文书
无违反计划生育证明格式
2015/06/24 职场文书
CSS3 Tab动画实例之背景切换动态效果
2021/08/23 HTML / CSS
SQLyog的下载、安装、破解、配置教程(MySQL可视化工具安装)
2022/09/23 MySQL