跟老齐学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 相关文章推荐
编写Python脚本来获取mp3文件tag信息的教程
May 04 Python
举例讲解Python中metaclass元类的创建与使用
Jun 30 Python
Python实现随机生成有效手机号码及身份证功能示例
Jun 05 Python
Python之os操作方法(详解)
Jun 15 Python
Python调用C# Com dll组件实战教程
Oct 12 Python
Linux(Redhat)安装python3.6虚拟环境(推荐)
May 05 Python
python3的输入方式及多组输入方法
Oct 17 Python
Windows下安装Scrapy
Oct 17 Python
Django框架视图介绍与使用详解
Jul 18 Python
Django 创建后台,配置sqlite3教程
Nov 18 Python
python实现图片插入文字
Nov 26 Python
python中利用matplotlib读取灰度图的例子
Dec 07 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
用文本文件制作留言板提示(上)
2006/10/09 PHP
基于php冒泡排序算法的深入理解
2013/06/09 PHP
PHP使用pear自带的mail类库发邮件的方法
2015/07/08 PHP
Laravel框架路由设置与使用示例
2018/06/12 PHP
jquery JSON的解析方式
2009/07/25 Javascript
jquery判断浏览器类型的代码
2012/11/05 Javascript
jQuery插件slides实现无缝轮播图特效
2015/04/17 Javascript
浅谈被jQuery抛弃的函数及替代函数
2015/05/03 Javascript
jQuery实现div随意拖动的实例代码(通用代码)
2016/01/28 Javascript
JQuery validate插件Remote用法大全
2016/05/15 Javascript
jquery获取复选框checkbox的值实现方法
2016/05/30 Javascript
原生js获取iframe中dom元素--父子页面相互获取对方dom元素的方法
2016/08/05 Javascript
Vue.js每天必学之指令系统与自定义指令
2016/09/07 Javascript
纯JavaScript 实现flappy bird小游戏实例代码
2016/09/27 Javascript
AngularJS入门教程之Helloworld示例
2016/12/25 Javascript
javascript工厂模式和构造函数模式创建对象方法解析
2016/12/30 Javascript
jquery replace方法去空格
2017/05/08 jQuery
Vue下滚动到页面底部无限加载数据的示例代码
2018/04/22 Javascript
js判断复选框是否选中的方法示例【基于jQuery】
2019/10/10 jQuery
JS call()及apply()方法使用实例汇总
2020/07/11 Javascript
vue相同路由跳转强制刷新该路由组件操作
2020/08/05 Javascript
[02:28]PWL开团时刻DAY3——Ink Ice与DeMonsTer之间的勾心斗角
2020/11/03 DOTA
Python中__name__的使用实例
2015/04/14 Python
python 简单搭建阻塞式单进程,多进程,多线程服务的实例
2017/11/01 Python
Python基于滑动平均思想实现缺失数据填充的方法
2019/02/21 Python
python系列 文件操作的代码
2019/10/06 Python
selenium+python实现自动登陆QQ邮箱并发送邮件功能
2019/12/13 Python
python中绕过反爬虫的方法总结
2020/11/25 Python
总经理岗位职责描述
2014/02/08 职场文书
经济信息系毕业生自荐信
2014/06/02 职场文书
课外访万家心得体会
2014/09/03 职场文书
工作失职造成投诉的检讨书范文
2014/10/05 职场文书
中秋节慰问信
2015/02/15 职场文书
2020优秀员工演讲稿(三篇)
2019/10/17 职场文书
Python天气语音播报小助手
2021/09/25 Python
Win10玩csgo闪退如何解决?Win10玩csgo闪退的解决方法
2022/07/23 数码科技