while语句,提供了编写通用循环的一种方法,而for语句是用来遍历序列对象内的元素,并对每一个元素运行一个代码块。break,continue用在循环内,跳出整个循环或者跳出一次循环。
1、while循环
一、通常格式
格式:首行以及测试表达式,有一列或多列缩进语句的主体以及一个选用的else部分(控制权离开循环时而没有碰到break语句时会执行)
python会一直计算开投的测试,而后执行循环主体内的语句,直到测试返回假值为止。
while :
else:
二、例子
>>> while True:
... print "Type Ctrl+C to stop!"
>>> while x:
... print x,
... x=x[1:]
...
diege iege ege ge e
注意 print末尾的逗号,会使全部输出都出如今同一行。
>>> a,b=0,10
>>> while a
... print a,
... a+=1
...
0 1 2 3 4 5 6 7 8 9
Python并无其余语言中所谓的"do until”循环语句,不过咱们能够在循环主体底部以一个测试和break来实现相似的功能。
while True:
do something
if exitTest():break
三、对比shell的while语句
while 命令
do
命令1
命令2
done
在系统管理时经常使用与逐行读取一个文件并处理。
while read line
do
echo $line
done < /etc/rc.conf
shell中还有一个相似while的循环until
until 条件
do
命令1
命令2
done
EG:
IS_ROOT=`who |grep root`
until [ "$IS_ROOT" ]
do
echo 'root online'
sleep 2
done
2、 break continue pass和循环的else
break
跳出最近所在的循环(跳出整个循环语句)
continue
跳到最近所在循环的开头处(来到循环的首行,跳过本次循环)
pass
什么事也不作,只是空占位语句
循环else块
只有当循环正常离开时才会执行(也就是没有碰到break语句)
一、通常循环格式
加入break和continue语句后,while循环的通常格式以下:
while :
if :break
if :continue
if :pass
else:
break和continue能够出如今while(或for)循环主体的任何地方,但一般会进一步嵌套在if语句中,根据某些条件来采起对应的操做。
二、列子
pass
>>> while 1:pass
...
pass可用于空类,有时有指的是"之后会填上”,只是暂时用于填充函数主体而已:
>>> def func1():
... pass
continue
continue语句会当即跳到循环的顶端,开始下一次循环。
>>> while x:
... x=x-1
... if x%2!=0:continue
... print x,
...
8 6 4 2 0
这个例子中,若是是奇数就返回循环顶部,不会打印.是偶数就打印。
这个下面这个结果同样
>>> while x:
... x=x-1
... if x%2==0:
... print x,
...
8 6 4 2 0
注意这两个例子的print位置,第一个print是属于while块的,测试不经过下执行,测试经过就回到循环顶端,第二个是属于if块的,只有测试经过才打印
>>> while x:
... x=x-1
... if x%2==0:
... print x,
...break
break语句会马上离开循环。碰到break,位于其后的循环代码都不会执行。
while 1:
name=raw_input("Enter name:")
if name=='stop':break
age=raw_input("Enter age:")
print 'Hello',name,'=>',int(age)**2
当age不输入任何值时会报错。可使用try解决
while 1:
name=raw_input("Enter name:")
if name=='stop':break
age=raw_input("Enter age:")
try:
print 'Hello',name,'=>',int(age)**2
except:
print 'Please input age!'
else 只有当循环正常离开时才会执行(也就是没有碰到break语句【break的条件不知足】)
>>> while x:
... x=x-1
... print x
... else:
... print "over"
...
9
8
7
6
5
4
3
2
1
0
over
>>> x=10
>>> while x:
... x=x-1
... if x==5:break
... print x
... else:
... print "over"
...
9
8
7
6
3、for循环
for循环在Python中是一个通用的序列迭代器:能够遍历任何有序的序列对象内的元素。for语句可用于字符串,列表,元组,其余内置可迭代对象以及以后咱们可以经过类所建立的新对象。
一、通常格式
Python for循环的首行定义了一个赋值目标(或【一些目标】),以及你想遍历的对象,首行后面是你想重复的语句块(通常都有缩进)
for in :
else:
当ptyhon运行for循环时,会逐个将序列对象中的元素赋值给目标,而后为每一个元素执行循环主体。循环主体通常使用赋值的目标来引用序列中当前的元素,就好像那事遍历序列的游标。
for首行中用做赋值目标的变量名一般是for语句所在做用于的变量(多是新的)。这个变量名没有什么特别的,甚至能够在循环主体中修改。可是当控制权再次回到循环顶端时,就会自动被设成序列的下一个元素。循环以后,这个变量通常都仍是引用了最近所用过的元素,也就是序列中最后的元素,除非经过一个break语句退出了循环。
for语句也支持一个选用的else块,它的工做就像在while循环中同样:若是循环离开时没有碰到break语句,就会执行(也就是序列全部元素都被访问过了)
break和continue语句也可用在for循环中,就像while循环那样。for循环完整的格式以下:
for in :
if :break
if :conitnue
else:
对比shell的for循环
for 变量名 in 列表
do
命令1
命令1
done
for i in 1 2 3
do
echo $i
don
for i in `ls -1 /root`
do
echo $i
done
二、例子
1)基本应用
>>> x=[1,2,3,4,5]
>>> for i in x:
... print i
...
1
2
3
4
5
>>> for i in x:
... if i==3:break
... print i
...
1
2
>>> for i in x:
... print i
... if i==3:break
...
1
2
3
注意if语句的位置
> D={'name':['diege','lily','kelly'],'class':2012,'number':48}
>>> for i in D:
... print i,'=>',D[i]
...
number => 48
name => ['diege', 'lily', 'kelly']
class => 2012
多层
>>> for i in D:
... if type(D[i])==list:
... for l in D[i]:
... print l
... else:
... print D[i]
...
48
diege
lily
kelly
2012
for元组赋值
首行定义了一个赋值【一些目标】
>>> T=[(1,2),(3,4),(5,6)]
>>> for (a,b) in T:
... print a,b
...
1 2
3 4
5 6
for循环嵌套
遍历一个字典(或列表)包括字典,列表,元组的的语句
D={'game':'sjgame','version':[1.0,1.1,1.2,1.3],'useid':(1000,1001,1002,1003,1004),'character':{'WS':'wushi','FS':'fashi','MS':'moshi
'},'CP':'ice'}
for i in D:
if type(D[i])==list:
for l in D[i]:
print l
elif type(D[i])==tuple:
for t in D[i]:
print t
elif type(D[i])==dict:
for d in D[i]:
print d
else:
print D[i]
代替break的
>>> items=['diege',999,(3,7),1.3]
>>> tests=[(3,7),3.14]
>>> for key in tests:
... for item in items:
... if key==item:
... print key,'was found'
... break
... else:
... print key,'not found!'
...
(3, 7) was found
3.14 not found
有点相似查找的功能。
收集两个序列中相同元素
>>> seq1='diege'
>>> seq2='decgl'
>>> res=[]
>>> for x in seq1:
... if x in seq2:
... res.append(x)
...
>>>
>>> res
['d', 'e', 'g', 'e']
准确的说是显示seq1和seq2都用的在seq1一次顺序。
三、为何要在乎“文件扫描”
循环读取文件:while在文件结尾时使用break
>>> fl=open('/etc/rc.conf')
>>> while True:
... char=fl.read(1)
... if not char:break
... print char,
MS for循环打印出来的字体正常点,呵呵。
>>> for char in open('/etc/rc.conf'):for char in open('/etc/rc.conf').read():的缩写
... print char
...
使用while按行处理
>>> fl=open('/etc/rc.conf')
>>> while True:
... line=fl.readline()
... if not line:break
... print line,
...
按行读取文件文件时,for循环是最容易编写及执行最快的选择
>>> for line in open('/etc/rc.conf'):#默认read()
... print line
...
>>> for line in open('/etc/rc.conf').readlines():
... print line
...
readlines会一次把文件载入到行字符串的列表
>>> for line in open('/etc/rc.conf').xreadlines():
... print line
...
xreadlines则是按需求加载文字列,从而避免大型文件致使内存溢出。
每一个步骤所读取的数据越多,程序会员越快。
4、迭代器:初探
for循环能够用在任何【可迭代的对象】。这些迭代工具包括了for循环,列表解析,in成员关系测试,以及map内置函数等。
可迭代对象:若是对象是实际保存的序列,或者能够在迭代工具环境中(如for循环)一次产生一个对象的结果,就被看做是可迭代。
总之,可迭代对象包括实际序列和按照需求而计算的虚拟序列。
一、文件迭代器
文件对象有个方法名为readline,能够一次从一个文件中读取一行文本,每次调用readline方法时,就会前进到下一列,到文件末尾时,就会返回空字符串,能够经过它来检查从而跳出循环。文件对象有另一个方法next,差很少用有相同的效果。
>>> fl=open('/etc/rc.conf')
>>> fl.next()
'#apache22_enable="YES"\n'
>>> fl.next()
'# -- sysinstall generated deltas -- # Tue Feb 14 10:08:27 2012\n'
二者的区别在于,达到文件末尾时,next是引起内置的StopIteration异常,而不是返回空字符串。
这个接口就是python所谓的迭代协议:有next方法的对象会前进到下一个结果,而在一些列结果的末尾时,则会引起StopIteration.
在Python中,任何这类对象都认为是可迭代的。任何这类对象也能以for循环或其余迭代工具遍历,由于全部迭代工具内部工做起来都是在每次迭代中调用next,而且捕捉StopIteration异常来肯定什么时候离开。
逐行读取文本的最佳方式就是根本不要去读取,其替代的方法就是,让for循环在每轮自动调用next从而前进到下一行。
>>> for line in open('/etc/rc.conf'):
... print line.upper(),
逐行读取文件并转换为大写,注意没有能够从文件中读取内容。
这首读取文本文件的最佳方式,最简单,运行最快,内存使用状况最好。
>>> for line in open('/etc/rc.conf').readlines:
这种方式一次把文件都加载到内存。
二、其余内置类型迭代器
>>> D={'a':1,'b':2,'c':3}
>>> for key in D.keys():
... print key,D[key]
...
a 1
c 3
b 2
新版无需使用keys方法
>>> for key in D:
... print key,D[key]
...
a 1
c 3
b 2
三、其余迭代环境
列表解析,in成员关系,map内置函数以及其余内置工具(如sorted,sum)
>>> [line.upper() for line in open('/etc/rc.conf')]
>>> upper=[line.upper() for line in open('/etc/rc.conf')]
>>> map(str.upper,open('/etc/rc.conf'))
map对迭代对象中每个元素都应用一个函数调用,相似于列表解析,有局限性,因须要函数,而不是任意表达式。
>>> sorted(open('/etc/rc.conf')) #这个工具排序了,较新的内置函数,采用了迭代协议。应用于任何可迭代的对象上。
>>> sum([3,5,6,9]) #sum调用会计算任何可迭代对象内全部数字的和
23
而若是可迭代对象中的任何元素或者所有元素为True,内置函数就会返回True:all所有元素为True才返回True,有一个元素不为
True,都会返回flase
>>> any(['diege','','ni'])
True
>>> any(['diege','',''])
True
>>> all(['diege','','ni'])
False
>>> all(['diege','a','ni'])
True
其余工具:list和tuple内置函数(从可迭代对象建立新的对象),字符串join方法(在可迭代对象内字符串之间放入子字符串),以及序列赋值语句等。
>>> list(open('/etc/rc.conf'))
>>> tuple(open('/etc/rc.conf'))
>>> '&&'.join(open('/etc/rc.conf'))
>>> a,d,c,d=open('/etc/rc.conf')
四、用户定义的迭代器
yield语句能够把用户定义的函数变成可迭代的对象。若是的列表解析也能够经过生成器表达式支持次协议,而用户定义的类
也能经过__iter__或__getitem__运算符重载方法而变成迭代对象。用户定义的迭代器能够在这里的任何迭代环境中使用任意对象和运算。
5、编写循环的技巧
遍历序列时,首选for循环,for循环包括多数计数器式的循环,for比while容易写,执行时也比较快。
Python提供了两个内置函数,在for循环内定制迭代:
* 内置range函数返回连续整数列表,可做为for中的索引。
>>> range(5)
[0, 1, 2, 3, 4]
>>> range(5,10)
[5, 6, 7, 8, 9]
>>> range(5,10,2)
[5, 7, 9]
*内置 zip函数返回并行的元素元祖的列表,可用于在for中遍历数个序列
一、循环计算器:while和range
>>> range(5),range(2,5),range(3,10,2)
([0, 1, 2, 3, 4], [2, 3, 4], [3, 5, 7, 9])
步进为负时候为递减,默认递增
>>> range(5,-5,-1)
[5, 4, 3, 2, 1, 0, -1, -2, -3, -4]
range最经常使用于在for循环中,提供一种简单的方法,重复特定次数的动做。
>>> for i in range(3):
... print i,'pythons'
...
0 pythons
1 pythons
2 pythons
>>> for i in range(0,10,2):
... print i
...
0
2
4
6
8
若是真的要明确地掌控索引逻辑,能够用while循环来实现。
>>> X='diege'
>>> i=0
>>> while i
... print X[i];i+=1
...
d
i
e
g
e
也可使用for进行手动索引,也就是用range产生用于迭代的索引的列表
>>> range(len(X))
[0, 1, 2, 3, 4]
>>> for i in range(len(X)):print X[i],
...
d i e g e
二、非完备遍历:range
尽可能使用简单的for循环,不要用while,而且不要在for循环中使用range调用,只将其视为最后的选择,更简单的办法老是更好。
>>> for i in X:
... print i
...
d
i
e
g
e
使用range能够作更特殊的遍历种类。
>>> S='rhrhrfxvlwsocv'
>>> for i in range(0,len(S),2):print S[i]
...
r
r
r
x
l
s
c
更好的办法
>>> for x in S[::2]:print x
...
r
r
r
x
l
s
c
三、修改列表:range
可使用range和for的组合的常见场合就是在循环中遍历列表时并对其进行修改。如某些缘由某种理由要为列表中每一个元素都加1.
>>> L=[1,2,3,4,5]
>>> L
[1, 2, 3, 4, 5]
>>> for i in range(len(L)):
... L[i]+=1
...
>>> L
[2, 3, 4, 5, 6]
四、并行遍历:zip 和map
>>> L1=[1,2,3,4]
>>> L2=[5,6,7,8]
>>> zip(L1,L2)
[(1, 5), (2, 6), (3, 7), (4, 8)]
>>> for (x,y) in zip(L1,L2):
... print x,y,'--',x+y
...
1 5 -- 6
2 6 -- 8
3 7 -- 10
4 8 -- 12
zip从两列或者多列中提取出来元素配对。
>>> T1,T2,T3=(1,2,3),(4,5,6),(7,8,9)
>>> zip(T1,T2,T3)
[(1, 4, 7), (2, 5, 8), (3, 6, 9)]
当参数长度不一样时,zip会以最短序列的长度为准来截断所获得的元组:
>>> S1='ABC'
>>> S2='xyz123'
>>> zip(S1,S2)
[('A', 'x'), ('B', 'y'), ('C', 'z')]
内置map函数,用相似的方式把序列的元素配对起来,可是若是参数长度,不一样则会为较短的序列用None补齐。
>>> map(None,S1,S2)
[('A', 'x'), ('B', 'y'), ('C', 'z'), (None, '1'), (None, '2'), (None, '3')]
使用zip构造字典
>>> keys=['name','age','class']
>>> vals=['diege',18,2012]
>>> zip(keys,vals)
[('name', 'diege'), ('age', 18), ('class', 2012)]
前面学过dict()函数,能够将k:v组成元组按列表的形式传送给disc()产生字典。
而zip能够掺产生这种格式的列表。故可使用
dict(zip(keys,vals)) 构造字典
>>> dict(zip(keys,vals))
{'age': 18, 'name': 'diege', 'class': 2012}
>>> D5=dict(zip(keys,vals))
五、产生偏移和元素:enumerate
enumerate内置函数,同时产生偏移和元素
>>> S='diege'
>>> for (offset,item) in enumerate(S):
... print item,offset
...
d 0
i 1
e 2
g 3
e 4
这个方法有个next方法,每次遍历列表时,会返回一个(index,value)的元组,而咱们能在for中经过元组赋值运算将其分解。
>>> E=enumerate(S)
>>> E.next()
(0, 'd')
>>> E.next()
(1, 'i')
>>> E.next()
(2, 'e')
>>> E.next()
(3, 'g')
>>> E.next()
(4, 'e')
>>> E.next()
Traceback (most recent call last):
File "", line 1, in
StopIteration
6、列表解析:
>>> L=[1,2,3,4,5]
>>> for i in range(len(L)):
... L[I]+=10
... L
>>> L
[1, 2, 3, 4, 5]
这样解析方式已通过时,这里用单个表达式取代循环,来产生所须要的结果列表
>>> L=[1,2,3,4,5]
>>> L=[x+10 for x in L]
>>> L
[11, 12, 13, 14, 15]
一、列表解析基础
列表解析是写在方括号中的,由于它毕竟是一种建立新的列表的方式。它是咱们编写的任何表达式开始,而该表达式中使用了一个咱们所编写循环的变量(x+10)。后面所接的就是for循环的首行,指出循环变量的名称以及可迭代的对象(for x in L)
[【表达式】 for x in L【for循环行首】]
技术角度,列表解析毫不是必需要求。由于可使用for循环,在遍历的过程当中把表达式结果加在列表上。
>>> res=[]
>>> L
[11, 12, 13, 14, 15]
>>> for x in L:
... res.append(x+10)
...
>>> L
[11, 12, 13, 14, 15]
不过列表解析写起来更简明,这种建立结果列表的编码模式在Python中是很常见的工做。并且运行更快,是以C语言的速度执行。
二、对文件使用列表解析
>>> f=open('/etc/rc.conf')
>>> lines=f.readlines()
>>> lines
['#apache22_enable="YES"\n', '# -- sysinstall generated deltas -- # Tue Feb 14 10:08:27 2012\n', 'ifconfig_em1="inet 192.168.1.200 netmask 255.255.255.0"\n', '#ifconfig_em0="DHCP"\n', '# -- sysinstall generated deltas -- # Tue Feb 14 10:09:24 2012\n', 'ifconfig_em1="inet 192.168.1.200 netmask 255.255.255.0"\n', '#hostname="ofreebsd.corp.icee.cn"\n', 'hostname="ofreebsd.skylog.cn"\n', '# -- sysinstall generated deltas -- # Tue Feb 14 10:12:04 2012\n', 'sshd_enable="YES"\n', '#mysql_enable="YES"\n']
列表中包含的有换行符,若是想去掉换行符怎么办呢?
想到字符串的rstrip方法,可是怎么应用呢?也可使用(line[:-1]也能够
>>> lines=[line.rstrip() for line in lines]
>>> lines
['#apache22_enable="YES"', '# -- sysinstall generated deltas -- # Tue Feb 14 10:08:27 2012', 'ifconfig_em1="inet 192.168.1.200 netmask 255.255.255.0"', '#ifconfig_em0="DHCP"', '# -- sysinstall generated deltas -- # Tue Feb 14 10:09:24 2012', 'ifconfig_em1="inet 192.168.1.200 netmask 255.255.255.0"', '#hostname="ofreebsd.corp.icee.cn"', 'hostname="ofreebsd.skylog.cn"', '# -- sysinstall generated deltas -- # Tue Feb 14 10:12:04 2012', 'sshd_enable="YES"', '#mysql_enable="YES"']
若是是打开文件读取文件,彻底能够不用事先打开,能够在表达式内开启它。
>>> lines=[line.rstrip() for line in open('/etc/rc.conf')]
三、扩展列表解析语句
列表解析在实际使用中能够更高级。表达式中嵌套的for循环能够结合一个if分句来过滤测试不为真的结果元素,这但是一项有用的扩展功能。
重复上一个例子,但咱们只需开头不为#的文字行。
>>> lines=[line.rstrip() for line in open('/etc/rc.conf') if line[0]!='#']
>>> lines
['ifconfig_em1="inet 192.168.1.200 netmask 255.255.255.0"', 'ifconfig_em1="inet 192.168.1.200 netmask 255.255.255.0"', 'hostname="ofreebsd.skylog.cn"', 'sshd_enable="YES"']
更复杂的状况,列表解析也能够含有嵌套循环,写成一系列的for分句。实际上,其完整的语句可接纳任意数目的for分句,而每一个分区均可以结合一个可选的if分句
>>> [x+y for x in 'abc' for y in 'lmn']
['al', 'am', 'an', 'bl', 'bm', 'bn', 'cl', 'cm', 'cn']
对一个字符串中的每一个x,以及另外一个字符串中的每一个y,建立x+y合并的列表。收集两个字符串字符的排列组合python