循環(huán),也是現(xiàn)實(shí)生活中常見的現(xiàn)象,我們常說日復(fù)一日,就是典型的循環(huán)。又如:日月更迭,斗轉(zhuǎn)星移,無(wú)不是循環(huán);王朝更迭;子子孫孫,繁衍不息,從某個(gè)角度看也都是循環(huán)。
編程語(yǔ)言就是要解決現(xiàn)實(shí)問題的,因此也少不了要循環(huán)。
在python中,循環(huán)有一個(gè)語(yǔ)句:for語(yǔ)句。
其基本結(jié)構(gòu)是:
for 循環(huán)規(guī)則:
操作語(yǔ)句
從這個(gè)基本結(jié)構(gòu)看,有著同if條件語(yǔ)句類似的地方:都有冒號(hào);語(yǔ)句塊都要縮進(jìn)。是的,這是不可或缺的。
前面介紹print語(yǔ)句的時(shí)候,出現(xiàn)了一個(gè)簡(jiǎn)單例子。重復(fù)一個(gè)類似的:
>>> hello = "world"
>>> for i in hello:
... print i
...
w
o
r
l
d
這個(gè)for循環(huán)是怎么工作的呢?
因?yàn)榭梢砸餐ㄟ^使用索引(偏移量),得到序列對(duì)象的某個(gè)元素。所以,還可以通過下面的循環(huán)方式實(shí)現(xiàn)同樣效果:
>>> for i in range(len(hello)):
... print hello[i]
...
w
o
r
l
d
其工作方式是:
range()
,關(guān)于它的用法,繼續(xù)閱讀,就能看到了。以上的循環(huán)舉例中,顯示了對(duì)str的字符依次獲取,也涉及了list,感覺不過癮呀。那好,看下面對(duì)list的循環(huán):
>>> ls_line
['Hello', 'I am qiwsir', 'Welcome you', '']
>>> for word in ls_line:
... print word
...
Hello
I am qiwsir
Welcome you
>>> for i in range(len(ls_line)):
... print ls_line[i]
...
Hello
I am qiwsir
Welcome you
這個(gè)內(nèi)建函數(shù),非常有必要給予說明,因?yàn)樗鼤?huì)經(jīng)常被使用。一般形式是range(start, stop[, step])
要研究清楚一些函數(shù)特別是內(nèi)置函數(shù)的功能,建議看官首先要明白內(nèi)置函數(shù)名稱的含義。因?yàn)樵趐ython中,名稱不是隨便取的,是代表一定意義的。所謂:名不正言不順。
range
n. 范圍;幅度;排;山脈 vi. (在...內(nèi))變動(dòng);平行,列為一行;延伸;漫游;射程達(dá)到 vt. 漫游;放牧;使并列;歸類于;來(lái)回走動(dòng)
在具體實(shí)驗(yàn)之前,還是按照管理,摘抄一段官方文檔的原話,讓我們能夠深刻理解之:
This is a versatile function to create lists containing arithmetic progressions. It is most often used in for loops. The arguments must be plain integers. If the step argument is omitted, it defaults to 1. If the start argument is omitted, it defaults to 0. The full form returns a list of plain integers [start, start + step, start + 2 step, ...]. If step is positive, the last element is the largest start + i step less than stop; if step is negative, the last element is the smallest start + i * step greater than stop. step must not be zero (or else ValueError is raised).
從這段話,我們可以得出關(guān)于range()
函數(shù)的以下幾點(diǎn):
在實(shí)驗(yàn)開始之前,再解釋range(start,stop[,step])的含義:
實(shí)驗(yàn)開始,請(qǐng)以各項(xiàng)對(duì)照前面的講述:
>>> range(9) #stop=9,別的都沒有寫,含義就是range(0,9,1)
[0, 1, 2, 3, 4, 5, 6, 7, 8] #從0開始,步長(zhǎng)為1,增加,直到小于9的那個(gè)數(shù)
>>> range(0,9)
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> range(0,9,1)
[0, 1, 2, 3, 4, 5, 6, 7, 8]
>>> range(1,9) #start=1
[1, 2, 3, 4, 5, 6, 7, 8]
>>> range(0,9,2) #step=2,每個(gè)元素等于start+i*step,
[0, 2, 4, 6, 8]
僅僅解釋一下range(0,9,2)
熟悉了上面的計(jì)算過程,看看下面的輸入誰(shuí)是什么結(jié)果?
>>> range(-9)
我本來(lái)期望給我返回[0,-1,-2,-3,-4,-5,-6,-7,-8],我的期望能實(shí)現(xiàn)嗎?
分析一下,這里start=0,step=1,stop=-9.
第一個(gè)值是0;第二個(gè)是start+1*step,將上面的數(shù)代入,應(yīng)該是1,但是最后一個(gè)還是-9,顯然出現(xiàn)問題了。但是,python在這里不報(bào)錯(cuò),它返回的結(jié)果是:
>>> range(-9)
[]
>>> range(0,-9)
[]
>>> range(0)
[]
報(bào)錯(cuò)和返回結(jié)果,是兩個(gè)含義,雖然返回的不是我們要的。應(yīng)該如何修改呢?
>>> range(0,-9,-1)
[0, -1, -2, -3, -4, -5, -6, -7, -8]
>>> range(0,-9,-2)
[0, -2, -4, -6, -8]
有了這個(gè)內(nèi)置函數(shù),很多事情就簡(jiǎn)單了。比如:
>>> range(0,100,2)
[0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28, 30, 32, 34, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, 80, 82, 84, 86, 88, 90, 92, 94, 96, 98]
100以內(nèi)的自然數(shù)中的偶數(shù)組成的list,就非常簡(jiǎn)單地搞定了。
思考一個(gè)問題,現(xiàn)在有一個(gè)列表,比如是["I","am","a","pythoner","I","am","learning","it","with","qiwsir"],要得到這個(gè)list的所有序號(hào)組成的list,但是不能一個(gè)一個(gè)用手指頭來(lái)數(shù)。怎么辦?
請(qǐng)沉思兩分鐘之后,自己實(shí)驗(yàn)一下,然后看下面。
>>> pythoner
['I', 'am', 'a', 'pythoner', 'I', 'am', 'learning', 'it', 'with', 'qiwsir']
>>> py_index = range(len(pythoner)) #以len(pythoner)為stop的值
>>> py_index
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
再用手指頭指著pythoner里面的元素,數(shù)一數(shù),是不是跟結(jié)果一樣。
例:找出100以內(nèi)的能夠被3整除的正整數(shù)。
分析:這個(gè)問題有兩個(gè)限制條件,第一是100以內(nèi)的正整數(shù),根據(jù)前面所學(xué),可以用range(1,100)來(lái)實(shí)現(xiàn);第二個(gè)是要解決被3整除的問題,假設(shè)某個(gè)正整數(shù)n,這個(gè)數(shù)如果能夠被3整除,也就是n%3(%是取余數(shù))為0.那么如何得到n呢,就是要用for循環(huán)。
以上做了簡(jiǎn)單分析,要實(shí)現(xiàn)流程,還需要細(xì)化一下。按照前面曾經(jīng)講授過的一種方法,要畫出問題解決的流程圖。
下面寫代碼就是按圖索驥了。
代碼:
#! /usr/bin/env python
#coding:utf-8
aliquot = []
for n in range(1,100):
if n%3 == 0:
aliquot.append(n)
print aliquot
代碼運(yùn)行結(jié)果:
[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]
上面的代碼中,將for循環(huán)和if條件判斷都用上了。
不過,感覺有點(diǎn)麻煩,其實(shí)這么做就可以了:
>>> range(3,100,3)
[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]
所有的序列類型對(duì)象,都能夠用for來(lái)循環(huán)。比如:
>>> name_str = "qiwsir"
>>> for i in name_str: #可以對(duì)str使用for循環(huán)
... print i,
...
q i w s i r
>>> name_list = list(name_str)
>>> name_list
['q', 'i', 'w', 's', 'i', 'r']
>>> for i in name_list: #對(duì)list也能用
... print i,
...
q i w s i r
>>> name_set = set(name_str) #set還可以用
>>> name_set
set(['q', 'i', 's', 'r', 'w'])
>>> for i in name_set:
... print i,
...
q i s r w
>>> name_tuple = tuple(name_str)
>>> name_tuple
('q', 'i', 'w', 's', 'i', 'r')
>>> for i in name_tuple: #tuple也能呀
... print i,
...
q i w s i r
>>> name_dict={"name":"qiwsir","lang":"python","website":"qiwsir.github.io"}
>>> for i in name_dict: #dict也不例外,這里本質(zhì)上是將字典的鍵拿出來(lái),成為序列后進(jìn)行循環(huán)
... print i,"-->",name_dict[i]
...
lang --> python
website --> qiwsir.github.io
name --> qiwsir
在用for來(lái)循環(huán)讀取字典鍵值對(duì)上,需要多說幾句。
有這樣一個(gè)字典:
>>> a_dict = {"name":"qiwsir", "lang":"python", "email":"qiwsir@gmail.com", "website":"www.itdiffer.com"}
曾記否?在《字典(2)》中有獲得字典鍵、值的函數(shù):items/iteritems/keys/iterkeys/values/itervalues,通過這些函數(shù)得到的是鍵或者值的列表。
>>> for k in a_dict.keys():
... print k, a_dict[k]
...
lang python
website www.itdiffer.com
name qiwsir
email qiwsir@gmail.com
這是最常用的一種獲得字典鍵/值對(duì)的方法,而且效率也不錯(cuò)。
>>> for k,v in a_dict.items():
... print k,v
...
lang python
website www.itdiffer.com
name qiwsir
email qiwsir@gmail.com
>>> for k,v in a_dict.iteritems():
... print k,v
...
lang python
website www.itdiffer.com
name qiwsir
email qiwsir@gmail.com
這兩種方法也能夠?qū)崿F(xiàn)同樣的效果,但是因?yàn)橛辛松厦娴姆椒?,一般就少用了。但是,用也無(wú)妨,特別是第二個(gè)iteritems()
,效率也是挺高的。
但是,要注意下面的方法:
>>> for k in a_dict.keys():
... print k, a_dict[k]
...
lang python
website www.itdiffer.com
name qiwsir
email qiwsir@gmail.com
這種方法其實(shí)是不提倡的,雖然實(shí)現(xiàn)了同樣的效果,但是效率常常是比較低的。切記。
>>> for v in a_dict.values():
... print v
...
python
www.itdiffer.com
qiwsir
qiwsir@gmail.com
>>> for v in a_dict.itervalues():
... print v
...
python
www.itdiffer.com
qiwsir
qiwsir@gmail.com
單獨(dú)取values,推薦第二種方法。
更多建議: