循環,也是現實生活中常見的現象,我們常說日復一日,就是典型的循環。又如:日月更迭,斗轉星移,無不是循環;王朝更迭;子子孫孫,繁衍不息,從某個角度看也都是循環。
編程語言就是要解決現實問題的,因此也少不了要循環。
在python中,循環有一個語句:for語句。
其基本結構是:
~~~
for 循環規則:
操作語句
~~~
從這個基本結構看,有著同if條件語句類似的地方:都有冒號;語句塊都要縮進。是的,這是不可或缺的。
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/123.md#簡單的for循環例子)簡單的for循環例子
前面介紹print語句的時候,出現了一個簡單例子。重復一個類似的:
~~~
>>> hello = "world"
>>> for i in hello:
... print i
...
w
o
r
l
d
~~~
這個for循環是怎么工作的呢?
1. hello這個變量引用的是"world"這個str類型的數據
2. 變量 i 通過hello找到它所引用的對象"world",因為str類型的數據屬于序列類型,能夠進行索引,于是就按照索引順序,從第一字符開始,依次獲得該字符的引用。
3. 當 i="w"的時候,執行print i,打印出了字母w,結束之后循環第二次,讓 i="e",然后執行print i,打印出字母e,如此循環下去,一直到最后一個字符被打印出來,循環自動結束。注意,每次打印之后,要換行。如果不想換行,怎么辦?參見[《語句(1)》](https://github.com/qiwsir/StarterLearningPython/blob/master/121.md)中關于print語句。
因為可以也通過使用索引(偏移量),得到序列對象的某個元素。所以,還可以通過下面的循環方式實現同樣效果:
~~~
>>> for i in range(len(hello)):
... print hello[i]
...
w
o
r
l
d
~~~
其工作方式是:
1. len(hello)得到hello引用的字符串的長度,為5
2. range(len(hello),就是range(5),也就是[0, 1, 2, 3, 4],對應這"world"每個字母索引,也可以稱之為偏移量。這里應用了一個新的函數`range()`,關于它的用法,繼續閱讀,就能看到了。
3. for i in range(len(hello)),就相當于for i in [0,1,2,3,4],讓i依次等于list中的各個值。當i=0時,打印hello[0],也就是第一個字符。然后順序循環下去,直到最后一個i=4為止。
以上的循環舉例中,顯示了對str的字符依次獲取,也涉及了list,感覺不過癮呀。那好,看下面對list的循環:
~~~
>>> 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
~~~
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/123.md#rangestartstop-step)range(start,stop[, step])
這個內建函數,非常有必要給予說明,因為它會經常被使用。一般形式是`range(start, stop[, step])`
要研究清楚一些函數特別是內置函數的功能,建議看官首先要明白內置函數名稱的含義。因為在python中,名稱不是隨便取的,是代表一定意義的。所謂:名不正言不順。
> range
>
> n. 范圍;幅度;排;山脈 vi. (在...內)變動;平行,列為一行;延伸;漫游;射程達到 vt. 漫游;放牧;使并列;歸類于;來回走動
在具體實驗之前,還是按照管理,摘抄一段[官方文檔的原話](https://docs.python.org/2/library/functions.html#range),讓我們能夠深刻理解之:
> 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).
從這段話,我們可以得出關于`range()`函數的以下幾點:
* 這個函數可以創建一個數字元素組成的列表。
* 這個函數最常用于for循環(關于for循環,馬上就要涉及到了)
* 函數的參數必須是整數,默認從0開始。返回值是類似[start, start + step, start + 2*step, ...]的列表。
* step默認值是1。如果不寫,就是按照此值。
* 如果step是正數,返回list的最最后的值不包含stop值,即start+i*step這個值小于stop;如果step是負數,start+i*step的值大于stop。
* step不能等于零,如果等于零,就報錯。
在實驗開始之前,再解釋range(start,stop[,step])的含義:
* start:開始數值,默認為0,也就是如果不寫這項,就是認為start=0
* stop:結束的數值,必須要寫的。
* step:變化的步長,默認是1,也就是不寫,就是認為步長為1。堅決不能為0
實驗開始,請以各項對照前面的講述:
~~~
>>> range(9) #stop=9,別的都沒有寫,含義就是range(0,9,1)
[0, 1, 2, 3, 4, 5, 6, 7, 8] #從0開始,步長為1,增加,直到小于9的那個數
>>> 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,每個元素等于start+i*step,
[0, 2, 4, 6, 8]
~~~
僅僅解釋一下range(0,9,2)
* 如果是從0開始,步長為1,可以寫成range(9)的樣子,但是,如果步長為2,寫成range(9,2)的樣子,計算機就有點糊涂了,它會認為start=9,stop=2。所以,在步長不為1的時候,切忌,要把start的值也寫上。
* start=0,step=2,stop=9.list中的第一個值是start=0,第二個值是start+1*step=2(注意,這里是1,不是2,不要忘記,前面已經講過,不論是list還是str,對元素進行編號的時候,都是從0開始的),第n個值就是start+(n-1)*step。直到小于stop前的那個值。
熟悉了上面的計算過程,看看下面的輸入誰是什么結果?
~~~
>>> range(-9)
~~~
我本來期望給我返回[0,-1,-2,-3,-4,-5,-6,-7,-8],我的期望能實現嗎?
分析一下,這里start=0,step=1,stop=-9.
第一個值是0;第二個是start+1*step,將上面的數代入,應該是1,但是最后一個還是-9,顯然出現問題了。但是,python在這里不報錯,它返回的結果是:
~~~
>>> range(-9)
[]
>>> range(0,-9)
[]
>>> range(0)
[]
~~~
報錯和返回結果,是兩個含義,雖然返回的不是我們要的。應該如何修改呢?
~~~
>>> range(0,-9,-1)
[0, -1, -2, -3, -4, -5, -6, -7, -8]
>>> range(0,-9,-2)
[0, -2, -4, -6, -8]
~~~
有了這個內置函數,很多事情就簡單了。比如:
~~~
>>> 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以內的自然數中的偶數組成的list,就非常簡單地搞定了。
思考一個問題,現在有一個列表,比如是["I","am","a","pythoner","I","am","learning","it","with","qiwsir"],要得到這個list的所有序號組成的list,但是不能一個一個用手指頭來數。怎么辦?
請沉思兩分鐘之后,自己實驗一下,然后看下面。
~~~
>>> 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里面的元素,數一數,是不是跟結果一樣。
**例:**找出100以內的能夠被3整除的正整數。
**分析:**這個問題有兩個限制條件,第一是100以內的正整數,根據前面所學,可以用range(1,100)來實現;第二個是要解決被3整除的問題,假設某個正整數n,這個數如果能夠被3整除,也就是n%3(%是取余數)為0.那么如何得到n呢,就是要用for循環。
以上做了簡單分析,要實現流程,還需要細化一下。按照前面曾經講授過的一種方法,要畫出問題解決的流程圖。
[](https://github.com/qiwsir/StarterLearningPython/blob/master/1images/12301.png)
下面寫代碼就是按圖索驥了。
代碼:
~~~
#! /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]
~~~
上面的代碼中,將for循環和if條件判斷都用上了。
不過,感覺有點麻煩,其實這么做就可以了:
~~~
>>> 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]
~~~
## [](https://github.com/qiwsir/StarterLearningPython/blob/master/123.md#能夠用來for的對象)能夠用來for的對象
所有的序列類型對象,都能夠用for來循環。比如:
~~~
>>> name_str = "qiwsir"
>>> for i in name_str: #可以對str使用for循環
... 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: #對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也不例外,這里本質上是將字典的鍵拿出來,成為序列后進行循環
... print i,"-->",name_dict[i]
...
lang --> python
website --> qiwsir.github.io
name --> qiwsir
~~~
在用for來循環讀取字典鍵值對上,需要多說幾句。
有這樣一個字典:
~~~
>>> a_dict = {"name":"qiwsir", "lang":"python", "email":"qiwsir@gmail.com", "website":"www.itdiffer.com"}
~~~
曾記否?在[《字典(2)》](https://github.com/qiwsir/StarterLearningPython/blob/master/117.md)中有獲得字典鍵、值的函數:items/iteritems/keys/iterkeys/values/itervalues,通過這些函數得到的是鍵或者值的列表。
~~~
>>> for k in a_dict.keys():
... print k, a_dict[k]
...
lang python
website www.itdiffer.com
name qiwsir
email qiwsir@gmail.com
~~~
這是最常用的一種獲得字典鍵/值對的方法,而且效率也不錯。
~~~
>>> 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
~~~
這兩種方法也能夠實現同樣的效果,但是因為有了上面的方法,一般就少用了。但是,用也無妨,特別是第二個`iteritems()`,效率也是挺高的。
但是,要注意下面的方法:
~~~
>>> for k in a_dict.keys():
... print k, a_dict[k]
...
lang python
website www.itdiffer.com
name qiwsir
email qiwsir@gmail.com
~~~
這種方法其實是不提倡的,雖然實現了同樣的效果,但是效率常常是比較低的。切記。
~~~
>>> 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
~~~
單獨取values,推薦第二種方法。
- 第零章 預備
- 關于Python的故事
- 從小工到專家
- Python安裝
- 集成開發環境
- 第壹章 基本數據類型
- 數和四則運算
- 除法
- 常用數學函數和運算優先級
- 寫一個簡單的程序
- 字符串(1)
- 字符串(2)
- 字符串(3)
- 字符串(4)
- 字符編碼
- 列表(1)
- 列表(2)
- 列表(3)
- 回顧list和str
- 元組
- 字典(1)
- 字典(2)
- 集合(1)
- 集合(2)
- 第貳章 語句和文件
- 運算符
- 語句(1)
- 語句(2)
- 語句(3)
- 語句(4)
- 語句(5)
- 文件(1)
- 文件(2)
- 迭代
- 練習
- 自省
- 第叁章 函數
- 函數(1)
- 函數(2)
- 函數(3)
- 函數(4)
- 函數練習
- 第肆章 類
- 類(1)
- 類(2)
- 類(3)
- 類(4)
- 類(5)
- 多態和封裝
- 特殊方法(1)
- 特殊方法(2)
- 迭代器
- 生成器
- 上下文管理器
- 第伍章 錯誤和異常
- 錯誤和異常(1)
- 錯誤和異常(2)
- 錯誤和異常(3)
- 第陸章 模塊
- 編寫模塊
- 標準庫(1)
- 標準庫(2)
- 標準庫(3)
- 標準庫(4)
- 標準庫(5)
- 標準庫(6)
- 標準庫(7)
- 標準庫(8)
- 第三方庫
- 第柒章 保存數據
- 將數據存入文件
- mysql數據庫(1)
- MySQL數據庫(2)
- mongodb數據庫(1)
- SQLite數據庫
- 電子表格
- 第捌章 用Tornado做網站
- 為做網站而準備
- 分析Hello
- 用tornado做網站(1)
- 用tornado做網站(2)
- 用tornado做網站(3)
- 用tornado做網站(4)
- 用tornado做網站(5)
- 用tornado做網站(6)
- 用tornado做網站(7)
- 第玖章 科學計算
- 為計算做準備
- Pandas使用(1)
- Pandas使用(2)
- 處理股票數據
- 附:網絡文摘
- 如何成為Python高手
- ASCII、Unicode、GBK和UTF-8字符編碼的區別聯系