最近在慕課網(wǎng)學(xué)習(xí)廖雪峰老師的Python進(jìn)階課程,做筆記總結(jié)一下重點(diǎn)。
基本變量及其類型
變量
在Python中,能夠直接處理的數(shù)據(jù)類型有以下幾種:
整數(shù)
如-100,0xdf92
浮點(diǎn)數(shù)
如2.55,1.23e9
字符串
字符串是以 ' '或'' ''括起來(lái)的任意文本,如'xyz',''lmn''
布爾值
在Python中,可以直接用True、False
表示布爾值(請(qǐng)注意大小寫),也可以通過(guò)布爾運(yùn)算計(jì)算出來(lái)。
布爾值可以用and、or和not運(yùn)算
空值
空值是Python里一個(gè)特殊的值,用None表示。None不能理解為0,因?yàn)?是有意義的,而None是一個(gè)特殊的空值
print語(yǔ)句
打印語(yǔ)句
>>>print 'hello, world'
hello, world```
>打印多個(gè)字符串
print 'I','love','Python'
I love Python```
打印運(yùn)算結(jié)果
>>>print 2+3
5```
print '100 + 200 =', 100 + 200
100 + 200 = 300 ```
注釋
Python的注釋以 #開(kāi)頭,后面的文字直到行尾都算注釋
# 這一行全部都是注釋...
print 'hello' # 這也是注釋```
####什么是變量
在Python中,變量的概念基本上和初中代數(shù)的方程變量是一致的
在Python程序中,**變量**是用一個(gè)**變量名**表示,變量名必須是大小寫英文、數(shù)字和下劃線(_)的組合,且不能用數(shù)字開(kāi)頭
比如:
`a=1`
變量`a`是一個(gè)整數(shù)
`t_007 = 'T007'`
變量```t_007```是一個(gè)字符串
在Python中,等號(hào)`=`是賦值語(yǔ)句,可以把任意數(shù)據(jù)類型賦值給變量,同一個(gè)變量可以反復(fù)賦值,而且可以是不同類型的變量。這種變量本身類型不固定的語(yǔ)言稱之為**動(dòng)態(tài)語(yǔ)言**,與之對(duì)應(yīng)的是**靜態(tài)語(yǔ)言**。
####定義字符串
* 如果字符串本身包含'怎么辦?比如我們要表示字符串` I'm OK `,這時(shí),可以用`" "`括起來(lái)表示:
`"I'm OK"`
* 類似的,如果字符串包含`"`,我們就可以用`' '`
括起來(lái)表示:
`'Learn "Python" in imooc'`
* 如果字符串既包含`'`又包含`"`怎么辦?
這個(gè)時(shí)候,就需要對(duì)字符串的某些特殊字符進(jìn)行“轉(zhuǎn)義”,Python字符串用` \ `進(jìn)行轉(zhuǎn)義
要表示字符串` Bob said "I'm OK".`
由于` ' `和 `" `會(huì)引起歧義,因此,我們?cè)谒懊娌迦胍粋€(gè)`\ `表示這是一個(gè)普通字符,不代表字符串的起始,因此,這個(gè)字符串又可以表示為:
`'Bob said \"I\'m OK\".'`
**注意:**轉(zhuǎn)義字符` \ `不計(jì)入字符串的內(nèi)容中
常用的轉(zhuǎn)義字符還有:
\n 表示換行
\t 表示一個(gè)制表符
\\ 表示 \ 字符本身
####raw字符串與多行字符串
* 如果一個(gè)字符串包含很多需要轉(zhuǎn)義的字符,對(duì)每一個(gè)字符都進(jìn)行轉(zhuǎn)義會(huì)很麻煩。為了避免這種情況,我們可以在字符串前面加個(gè)前綴`r `,表示這是一個(gè) raw 字符串,里面的字符就不需要轉(zhuǎn)義了。例如:
r'(_)/ (_)/'```
但是r'...'表示法不能表示多行字符串,也不能表示包含'和 "的字符串
- 如果要表示多行字符串,可以用
'''...'''表示:
'''Line 1
Line 2
Line 3'''
上面這個(gè)字符串的表示方法和下面的是完全一樣的:
'Line 1\nLine 2\nLine 3' - 還可以在多行字符串前面添加
r,把這個(gè)多行字符串也變成一個(gè)raw字符串:
>>>print r''' "To be, or not to be": that is the question.
Whether it's nobler in the mind to suffer.'''
"To be, or not to be": that is the question.
Whether it's nobler in the mind to suffer.
Unicode字符串
如果中文字符串在Python環(huán)境下遇到 UnicodeDecodeError,這是因?yàn)?py文件保存的格式有問(wèn)題。可以在第一行添加注釋:
# -*- coding: utf-8 -*-```
如.py文件:
-- coding: utf-8 --
print '''靜夜思
床前明月光,
疑是地上霜。
舉頭望明月,
低頭思故鄉(xiāng)。
'''```
運(yùn)行得到:
靜夜思
床前明月光,
疑是地上霜。
舉頭望明月,
低頭思故鄉(xiāng)。
整數(shù)和浮點(diǎn)數(shù)
Python支持對(duì)整數(shù)和浮點(diǎn)數(shù)直接進(jìn)行四則混合運(yùn)算,運(yùn)算規(guī)則和數(shù)學(xué)上的四則運(yùn)算規(guī)則完全一致。
布爾類型
我們已經(jīng)了解了Python支持布爾類型的數(shù)據(jù),布爾類型只有True和False兩種值。
Python把0、空字符串' '和None看成 False,其他數(shù)值和非空字符串都看成True,如:
True and 'a=T' 計(jì)算結(jié)果是 'a=T'
繼續(xù)計(jì)算 'a=T' or 'a=F' 計(jì)算結(jié)果還是 'a=T'```
**要解釋上述結(jié)果,又涉及到 and 和 or 運(yùn)算的一條重要法則:短路計(jì)算。**
1. 在計(jì)算 `a and b `時(shí),如果 a 是 False,則根據(jù)與運(yùn)算法則,整個(gè)結(jié)果必定為 False,因此返回 a;如果 a 是 True,則整個(gè)計(jì)算結(jié)果必定取決與 b,因此返回 b。
2. 在計(jì)算 `a or b `時(shí),如果 a 是 True,則根據(jù)或運(yùn)算法則,整個(gè)計(jì)算結(jié)果必定為 True,因此返回 a;如果 a 是 False,則整個(gè)計(jì)算結(jié)果必定取決于 b,因此返回 b。
**所以Python解釋器在做布爾運(yùn)算時(shí),只要能提前確定計(jì)算結(jié)果,它就不會(huì)往后算了,直接返回結(jié)果。**
運(yùn)行如下代碼:
a = 'python'
print 'hello,', a or 'world'
b = ''
print 'hello,', b or 'world'```
打印結(jié)果為:
hello, python
hello, world```
___
###List和Tuple類型
####創(chuàng)建list
Python內(nèi)置的一種數(shù)據(jù)類型是列表:`list`。`list`是一種有序的集合,可以隨時(shí)添加和刪除其中的元素。
比如,列出班里所有同學(xué)的名字,就可以用一個(gè)list表示:
['Michael', 'Bob', 'Tracy']
['Michael', 'Bob', 'Tracy']```
list是數(shù)學(xué)意義上的有序集合,也就是說(shuō),list中的元素是按照順序排列的。
構(gòu)造list非常簡(jiǎn)單,按照上面的代碼,直接用 [ ]
把list的所有元素都括起來(lái),就是一個(gè)list對(duì)象。通常,我們會(huì)把list賦值給一個(gè)變量,這樣,就可以通過(guò)變量來(lái)引用list:
>>> classmates = ['Michael', 'Bob', 'Tracy']
>>> classmates # 打印classmates變量的內(nèi)容
['Michael', 'Bob', 'Tracy']```
由于Python是**動(dòng)態(tài)語(yǔ)言**,所以list中包含的元素并不要求都必須是同一種數(shù)據(jù)類型,我們完全可以在list中包含各種數(shù)據(jù):
L = ['Michael', 100, True]
一個(gè)元素也沒(méi)有的list,就是空l(shuí)ist:
empty_list = []```
按照索引訪問(wèn)list
由于list是一個(gè)有序集合,所以,我們可以用一個(gè)list按分?jǐn)?shù)從高到低表示出班里的3個(gè)同學(xué):
>>> L = ['Adam', 'Lisa', 'Bart']```
那我們?nèi)绾螐膌ist中獲取指定第 N 名的同學(xué)呢?方法是通過(guò)索引來(lái)獲取list中的指定元素。
(**需要特別注意的是**,索引從 0 開(kāi)始,也就是說(shuō),第一個(gè)元素的索引是0,第二個(gè)元素的索引是1,以此類推。)
因此,要打印第一名同學(xué)的名字,用 L[0]:
print L[0]
Adam```
要打印第四名同學(xué)的名字,用 L[3]:
>>> print L[3]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: list index out of range```
報(bào)錯(cuò)了!IndexError意思就是索引超出了范圍,因?yàn)樯厦娴膌ist只有3個(gè)元素,有效的索引是 0,1,2。
所以,使用索引時(shí),**千萬(wàn)注意不要越界**。
####倒序訪問(wèn)list
如何得到分?jǐn)?shù)最低的同學(xué)?
* 方法一
我們可以先數(shù)一數(shù)這個(gè) list,發(fā)現(xiàn)它包含3個(gè)元素,因此,最后一個(gè)元素的索引是2:
print L[2]
Bart```
- 方法二
Bart同學(xué)是最后一名,俗稱倒數(shù)第一,所以,我們可以用 -1 這個(gè)索引來(lái)表示最后一個(gè)元素:
>>> print L[-1]
Bart```
(注意:使用倒序索引時(shí),也要注意**不要越界**)
####添加新元素
今天,班里轉(zhuǎn)來(lái)一名新同學(xué) Paul,如何把新同學(xué)添加到現(xiàn)有的 list 中呢?
* 方法一
用 list 的 `append()` 方法,把新同學(xué)追加到 list 的末尾:
L = ['Adam', 'Lisa', 'Bart']
L.append('Paul')
print L
['Adam', 'Lisa', 'Bart', 'Paul']```
append()總是把新的元素添加到 list 的尾部
如果把Paul 同學(xué)添加到第一的位置怎么辦?
- 方法二
方法是用list的insert()方法,它接受兩個(gè)參數(shù),第一個(gè)參數(shù)是索引號(hào),第二個(gè)參數(shù)是待添加的新元素:
>>> L = ['Adam', 'Lisa', 'Bart']
>>> L.insert(0, 'Paul')
>>> print L
['Paul', 'Adam', 'Lisa', 'Bart']```
( 注意**`L.insert(0, 'Paul')`**的意思是,'Paul'將被添加到索引為 0 的位置上(也就是第一個(gè)),而原來(lái)索引為 0 的Adam同學(xué),以及后面的所有同學(xué),都自動(dòng)向后移動(dòng)一位。)
####從list刪除元素
Paul同學(xué)剛來(lái)幾天又要轉(zhuǎn)走了,那么我們?cè)趺窗裀aul 從現(xiàn)有的list中刪除呢?
* 如果Paul同學(xué)排在最后一個(gè),我們可以用list的`pop()`方法刪除:
L = ['Adam', 'Lisa', 'Bart', 'Paul']
L.pop()
'Paul'
print L
['Adam', 'Lisa', 'Bart']```
注意:pop()方法總是刪掉list的最后一個(gè)元素,并且它還返回這個(gè)元素,所以我們執(zhí)行 L.pop()后,會(huì)打印出 'Paul'。
- 如果Paul同學(xué)不是排在最后一個(gè)怎么辦?比如Paul同學(xué)排在第三:
>>> L = ['Adam', 'Lisa', 'Paul', 'Bart']```
要把Paul踢出list,我們就必須**先定位Paul的位置**。由于Paul的索引是2,因此,用 pop(2)
把Paul刪掉:
L.pop(2)
'Paul'
print L
['Adam', 'Lisa', 'Bart']```
從list替換元素
假設(shè)現(xiàn)在班里仍然是3名同學(xué):
>>> L = ['Adam', 'Lisa', 'Bart']```
現(xiàn)在,Bart同學(xué)要轉(zhuǎn)學(xué)走了,碰巧來(lái)了一個(gè)Paul同學(xué),要更新班級(jí)成員名單。
* 方法一
我們可以先把Bart刪掉(pop),再把Paul添加(append或insert)進(jìn)來(lái)。
* 方法二
L[2] = 'Paul'
print L
L = ['Adam', 'Lisa', 'Paul']```
對(duì)list中的某一個(gè)索引賦值,就可以直接用新的元素替換掉原來(lái)的元素,list包含的元素個(gè)數(shù)保持不變。
由于Bart還可以用 -1 做索引,因此,下面的代碼也可以完成同樣的替換工作:
>>> L[-1] = 'Paul'```
####創(chuàng)建tuple
tuple是另一種有序的列表,中文翻譯為“ 元組 ”。tuple 和 list 非常類似,但是,**tuple一旦創(chuàng)建完畢,就不能修改了!!!**
同樣是表示班里同學(xué)的名稱,用tuple表示如下:
t = ('Adam', 'Lisa', 'Bart')```
創(chuàng)建tuple和創(chuàng)建list唯一不同之處是用( )替代了[ ]。
現(xiàn)在,這個(gè)t就不能改變了,tuple沒(méi)有 append()方法,也沒(méi)有insert()和pop()方法。所以,新同學(xué)沒(méi)法直接往 tuple 中添加,老同學(xué)想退出 tuple 也不行。
獲取 tuple 元素的方式和 list 是一模一樣的,我們可以正常使用 t[0],t[-1]等索引方式訪問(wèn)元素,但是不能賦值成別的元素!!!
創(chuàng)建單元素tuple
tuple和list一樣,可以包含 0 個(gè)、1個(gè)和任意多個(gè)元素
- 創(chuàng)建包含 0 個(gè)元素的 tuple,也就是空tuple,直接用 ()表示:
>>> t = ()
>>> print t
()```
* 創(chuàng)建包含1個(gè)元素的 tuple
t = (1)
print t
1
好像哪里不對(duì)!t 不是 tuple ,而是整數(shù)1。**為什么**呢?
因?yàn)閌()`既可以表示tuple,又可以作為括號(hào)表示運(yùn)算時(shí)的優(yōu)先級(jí),結(jié)果 (1) 被Python解釋器計(jì)算出結(jié)果 1,導(dǎo)致我們得到的不是tuple,而是整數(shù) 1。
正是因?yàn)橛?)定義單元素的tuple有歧義,所以 Python 規(guī)定,單元素 tuple 要多加一個(gè)逗號(hào)`“,”`,這樣就避免了歧義:
t = (1,)
print t
(1,)```
Python在打印單元素tuple時(shí),也自動(dòng)添加了一個(gè)“,”,為了更明確地告訴你這是一個(gè)tuple。
多元素 tuple 加不加這個(gè)額外的“,”效果是一樣的:
>>> t = (1, 2, 3,)
>>> print t
(1, 2, 3)```
####“可變”的tuple
前面我們看到了tuple一旦創(chuàng)建就不能修改。現(xiàn)在,我們來(lái)看一個(gè)“可變”的tuple:
t = ('a', 'b', ['A', 'B'])```
注意到 t 有 3 個(gè)元素:'a','b'和一個(gè)list:['A', 'B']。list作為一個(gè)整體是tuple的第3個(gè)元素。list對(duì)象可以通過(guò) t[2] 拿到:
>>> L = t[2]```
然后,我們把list的兩個(gè)元素改一改:
L[0] = 'X'
L[1] = 'Y'```
再看看tuple的內(nèi)容:
>>> print t
('a', 'b', ['X', 'Y'])```
表面上看,tuple的元素確實(shí)變了,但其實(shí)變的不是 tuple 的元素,而是list的元素。
tuple一開(kāi)始指向的list并沒(méi)有改成別的list,所以,tuple所謂的**“不變”**是說(shuō),tuple的每個(gè)元素,指向永遠(yuǎn)不變。即**指向'a',就不能改成指向'b'**,指向一個(gè)list,就不能改成指向其他對(duì)象,但指向的這個(gè)list本身是可變的!
理解了**“指向不變”**后,要?jiǎng)?chuàng)建一個(gè)內(nèi)容也不變的tuple怎么做?那就必須保證tuple的每一個(gè)元素本身也不能變。
例如:
t = ('a', 'b', ('A', 'B'))```
就是不可變的。
條件判斷和循環(huán)
if語(yǔ)句
計(jì)算機(jī)之所以能做很多自動(dòng)化的任務(wù),因?yàn)樗梢宰约鹤鰲l件判斷。
比如,輸入用戶年齡,根據(jù)年齡打印不同的內(nèi)容,在Python程序中,可以用if語(yǔ)句實(shí)現(xiàn):
age = 20
if age >= 18:
print 'your age is', age
print 'adult'
print 'END'```
**注意: **<font color=#FF4500 >Python代碼的縮進(jìn)規(guī)則</font>。具有相同縮進(jìn)的代碼被視為代碼塊,上面的3,4行 print 語(yǔ)句就構(gòu)成一個(gè)代碼塊(但不包括第5行的print)。如果 if 語(yǔ)句判斷為 True,就會(huì)執(zhí)行這個(gè)代碼塊。
縮進(jìn)要嚴(yán)格按照Python的習(xí)慣寫法:<font color=#FF4500 >4個(gè)空格,不要使用Tab,更不要混合Tab和空格</font>,否則很容易造成因?yàn)榭s進(jìn)引起的語(yǔ)法錯(cuò)誤。
**注意**: if 語(yǔ)句后接表達(dá)式,然后用`:`表示代碼塊開(kāi)始。
如果在<font color=#FF4500 >Python交互環(huán)境下敲代碼</font>,還要特別<font color=#FF4500 >留意縮進(jìn)</font>,并且<font color=#FF4500 >退出縮進(jìn)需要多敲一行回車</font>:
age = 20
if age >= 18:
... print 'your age is', age
... print 'adult't = (1, 2, 3,)
>>> print t
(1, 2, 3)####“可變”的tuple 前面我們看到了tuple一旦創(chuàng)建就不能修改?,F(xiàn)在,我們來(lái)看一個(gè)“可變”的tuple:
>>> t = ('a', 'b', ['A', 'B'])**注意**到 t 有 3 個(gè)元素:**'a','b'**和一個(gè)list:**['A', 'B']**。list作為一個(gè)整體是tuple的第3個(gè)元素。list對(duì)象可以通過(guò) t[2] 拿到:
>>> L = t[2]然后,我們把list的兩個(gè)元素改一改:
>>> L[0] = 'X'
>>> L[1] = 'Y'再看看tuple的內(nèi)容:
>>> print t
('a', 'b', ['X', 'Y'])表面上看,tuple的元素確實(shí)變了,但其實(shí)變的不是 tuple 的元素,而是list的元素。 tuple一開(kāi)始指向的list并沒(méi)有改成別的list,所以,tuple所謂的**“不變”**是說(shuō),tuple的每個(gè)元素,指向永遠(yuǎn)不變。即**指向'a',就不能改成指向'b'**,指向一個(gè)list,就不能改成指向其他對(duì)象,但指向的這個(gè)list本身是可變的! 理解了**“指向不變”**后,要?jiǎng)?chuàng)建一個(gè)內(nèi)容也不變的tuple怎么做?那就必須保證tuple的每一個(gè)元素本身也不能變。 例如:
t = ('a', 'b', ('A', 'B'))就是不可變的。 ----------------- ###條件判斷和循環(huán) ####if語(yǔ)句 計(jì)算機(jī)之所以能做很多自動(dòng)化的任務(wù),因?yàn)樗梢宰约鹤鰲l件判斷。 比如,輸入用戶年齡,根據(jù)年齡打印不同的內(nèi)容,在Python程序中,可以用if語(yǔ)句實(shí)現(xiàn):
age = 20
if age >= 18:
print 'your age is', age
print 'adult'
print 'END'**注意: **<font color=#FF4500 >Python代碼的縮進(jìn)規(guī)則</font>。具有相同縮進(jìn)的代碼被視為代碼塊,上面的3,4行 print 語(yǔ)句就構(gòu)成一個(gè)代碼塊(但不包括第5行的print)。如果 if 語(yǔ)句判斷為 True,就會(huì)執(zhí)行這個(gè)代碼塊。 縮進(jìn)要嚴(yán)格按照Python的習(xí)慣寫法:<font color=#FF4500 >4個(gè)空格,不要使用Tab,更不要混合Tab和空格</font>,否則很容易造成因?yàn)榭s進(jìn)引起的語(yǔ)法錯(cuò)誤。 **注意**: if 語(yǔ)句后接表達(dá)式,然后用`:`表示代碼塊開(kāi)始。 如果在<font color=#FF4500 >Python交互環(huán)境下敲代碼</font>,還要特別<font color=#FF4500 >留意縮進(jìn)</font>,并且<font color=#FF4500 >退出縮進(jìn)需要多敲一行回車</font>:
>>> age = 20
>>> if age >= 18:
... print 'your age is', age
... print 'adult'
...
your age is 20
print t
(1, 2, 3)####“可變”的tuple 前面我們看到了tuple一旦創(chuàng)建就不能修改?,F(xiàn)在,我們來(lái)看一個(gè)“可變”的tuple:
>>> t = ('a', 'b', ['A', 'B'])**注意**到 t 有 3 個(gè)元素:**'a','b'**和一個(gè)list:**['A', 'B']**。list作為一個(gè)整體是tuple的第3個(gè)元素。list對(duì)象可以通過(guò) t[2] 拿到:
>>> L = t[2]然后,我們把list的兩個(gè)元素改一改:
>>> L[0] = 'X'
>>> L[1] = 'Y'再看看tuple的內(nèi)容:
>>> print t
('a', 'b', ['X', 'Y'])表面上看,tuple的元素確實(shí)變了,但其實(shí)變的不是 tuple 的元素,而是list的元素。 tuple一開(kāi)始指向的list并沒(méi)有改成別的list,所以,tuple所謂的**“不變”**是說(shuō),tuple的每個(gè)元素,指向永遠(yuǎn)不變。即**指向'a',就不能改成指向'b'**,指向一個(gè)list,就不能改成指向其他對(duì)象,但指向的這個(gè)list本身是可變的! 理解了**“指向不變”**后,要?jiǎng)?chuàng)建一個(gè)內(nèi)容也不變的tuple怎么做?那就必須保證tuple的每一個(gè)元素本身也不能變。 例如:
t = ('a', 'b', ('A', 'B'))就是不可變的。 ----------------- ###條件判斷和循環(huán) ####if語(yǔ)句 計(jì)算機(jī)之所以能做很多自動(dòng)化的任務(wù),因?yàn)樗梢宰约鹤鰲l件判斷。 比如,輸入用戶年齡,根據(jù)年齡打印不同的內(nèi)容,在Python程序中,可以用if語(yǔ)句實(shí)現(xiàn):
age = 20
if age >= 18:
print 'your age is', age
print 'adult'
print 'END'**注意: **<font color=#FF4500 >Python代碼的縮進(jìn)規(guī)則</font>。具有相同縮進(jìn)的代碼被視為代碼塊,上面的3,4行 print 語(yǔ)句就構(gòu)成一個(gè)代碼塊(但不包括第5行的print)。如果 if 語(yǔ)句判斷為 True,就會(huì)執(zhí)行這個(gè)代碼塊。 縮進(jìn)要嚴(yán)格按照Python的習(xí)慣寫法:<font color=#FF4500 >4個(gè)空格,不要使用Tab,更不要混合Tab和空格</font>,否則很容易造成因?yàn)榭s進(jìn)引起的語(yǔ)法錯(cuò)誤。 **注意**: if 語(yǔ)句后接表達(dá)式,然后用`:`表示代碼塊開(kāi)始。 如果在<font color=#FF4500 >Python交互環(huán)境下敲代碼</font>,還要特別<font color=#FF4500 >留意縮進(jìn)</font>,并且<font color=#FF4500 >退出縮進(jìn)需要多敲一行回車</font>:
>>> age = 20
>>> if age >= 18:
... print 'your age is', age
... print 'adult'
...
your age is 20
adult```
if-else語(yǔ)句
當(dāng) if 語(yǔ)句判斷表達(dá)式的結(jié)果為 True 時(shí),就會(huì)執(zhí)行 if 包含的代碼塊:
if age >= 18: print 'adult'```
如果我們想判斷年齡在18歲以下時(shí),打印出 'teenager',怎么辦?
可以用一個(gè) <font color=#FF4500 >if ... else ... </font>語(yǔ)句:
if age >= 18:
print 'adult'
else:
print 'teenager'```
if-elif-else語(yǔ)句
有的時(shí)候,一個(gè) if ... else ... 還不夠用。比如,根據(jù)年齡的劃分:
條件1:18歲或以上:adult
條件2:6歲或以上:teenager
條件3:6歲以下:kid```
要避免嵌套結(jié)構(gòu)的 if ... else ...,我們可以用 if ... 多個(gè)elif ... else ...的結(jié)構(gòu),一次寫完所有的規(guī)則:
if age >= 18:
print 'adult'
elif age >= 6:
print 'teenager'
elif age >= 3:
print 'kid'
else:
print 'baby'```
elif 意思就是 else if。這樣一來(lái),我們就寫出了結(jié)構(gòu)非常清晰的一系列條件判斷。
**特別注意: **這一系列條件判斷會(huì)從上到下依次判斷,如果某個(gè)判斷為 True,執(zhí)行完對(duì)應(yīng)的代碼塊,后面的條件判斷就直接忽略,不再執(zhí)行了
for循環(huán)
list或tuple可以表示一個(gè)有序集合。如果我們想依次訪問(wèn)一個(gè)list中的每一個(gè)元素呢?比如 list:
L = ['Adam', 'Lisa', 'Bart']```
Python的 for 循環(huán)就可以依次把list或tuple的每個(gè)元素迭代出來(lái):
L = ['Adam', 'Lisa', 'Bart']for name in L: print name```
注意: name 這個(gè)變量是在 for 循環(huán)中定義的,意思是,依次取出list中的每一個(gè)元素,并把元素賦值給 name,然后執(zhí)行for循環(huán)體(就是縮進(jìn)的代碼塊)。
這樣一來(lái),遍歷一個(gè)list或tuple就非常容易了。
while循環(huán)
和 for 循環(huán)不同的另一種循環(huán)是 while 循環(huán),while 循環(huán)不會(huì)迭代 list 或 tuple 的元素,而是根據(jù)表達(dá)式判斷循環(huán)是否結(jié)束。
比如要從 0 開(kāi)始打印不大于 N 的整數(shù):
N = 10
x = 0
while x < N:
print x
x = x + 1```
while循環(huán)每次先判斷 x < N,如果為True,則執(zhí)行循環(huán)體的代碼塊,否則,退出循環(huán)。
在循環(huán)體內(nèi),x = x + 1 會(huì)讓 x 不斷增加,最終因?yàn)?x < N 不成立而退出循環(huán)。
####break退出循環(huán)
用 for 循環(huán)或者 while 循環(huán)時(shí),如果要在循環(huán)體內(nèi)直接退出循環(huán),可以使用 break 語(yǔ)句
比如計(jì)算1至100的整數(shù)和,我們用while來(lái)實(shí)現(xiàn):
sum = 0
x = 1
while True:
sum = sum + x
x = x + 1
if x > 100:
break
print sum```
咋一看, while True 就是一個(gè)死循環(huán),但是在循環(huán)體內(nèi),我們還判斷了 x > 100 條件成立時(shí),用break語(yǔ)句退出循環(huán),這樣也可以實(shí)現(xiàn)循環(huán)的結(jié)束。
continue繼續(xù)循環(huán)
在循環(huán)過(guò)程中,可以用break退出當(dāng)前循環(huán),還可以用continue跳過(guò)后續(xù)循環(huán)代碼,繼續(xù)下一次循環(huán)。
現(xiàn)在老師只想統(tǒng)計(jì)及格分?jǐn)?shù)的平均分,就要把 x < 60 的分?jǐn)?shù)剔除掉,這時(shí),利用 continue,可以做到當(dāng) x < 60的時(shí)候,不繼續(xù)執(zhí)行循環(huán)體的后續(xù)代碼,直接進(jìn)入下一次循環(huán):
L = [75, 98, 59, 81, 66, 43, 69, 85]
sum = 0.0
n = 0
for x in L:
if x < 60:
continue
sum = sum + x
n = n + 1```
####多重循環(huán)
在循環(huán)內(nèi)部,還可以嵌套循環(huán),我們來(lái)看一個(gè)例子:
for x in ['A', 'B', 'C']:
for y in ['1', '2', '3']:
print x + y
x 每循環(huán)一次,y 就會(huì)循環(huán) 3 次,這樣,我們可以打印出一個(gè)全排列:
A1
A2
A3
B1
B2
B3
C1
C2
C3
__________
###Dict和Set類型
####什么是dict
我們已經(jīng)知道,list 和 tuple 可以用來(lái)表示順序集合,例如,班里同學(xué)的名字:
['Adam', 'Lisa', 'Bart']```
或者考試的成績(jī)列表:
[95, 85, 59]```
但是,要根據(jù)名字找到對(duì)應(yīng)的成績(jī),用兩個(gè) list 表示就不方便。
如果把名字和分?jǐn)?shù)關(guān)聯(lián)起來(lái),組成類似的查找表:
'Adam' ==> 95
'Lisa' ==> 85
'Bart' ==> 59```
那么給定一個(gè)名字,就可以直接查到分?jǐn)?shù)。
Python的 dict 就是專門干這件事的。用 dict 表示“名字”-“成績(jī)”的查找表如下:
d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}
我們把名字稱為key,對(duì)應(yīng)的成績(jī)稱為value,dict就是通過(guò) key 來(lái)查找 value。
花括號(hào) {} 表示這是一個(gè)dict,然后按照** key: value**, 寫出來(lái)即可。最后一個(gè) key: value 的逗號(hào)可以省略。
由于dict也是集合,len() 函數(shù)可以計(jì)算任意集合的大小:
>>> len(d)
3
注意: 一個(gè) key-value 算一個(gè),因此,dict大小為3。
訪問(wèn)dict
我們已經(jīng)能創(chuàng)建一個(gè)dict,用于表示名字和成績(jī)的對(duì)應(yīng)關(guān)系:
d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}```
那么,如何根據(jù)名字來(lái)查找對(duì)應(yīng)的成績(jī)呢?
可以簡(jiǎn)單地使用 `d[key]` 的形式來(lái)查找對(duì)應(yīng)的 value,這和 list 很像,不同之處是,**list 必須使用索引返回對(duì)應(yīng)的元素,而dict使用key:**
print d['Adam']
95
print d['Paul']
Traceback (most recent call last):
File "index.py", line 11, in <module>
print d['Paul']
KeyError: 'Paul'
**注意:** 通過(guò) key 訪問(wèn) dict 的value,只要 key 存在,dict就返回對(duì)應(yīng)的value。如果key不存在,會(huì)直接報(bào)錯(cuò):KeyError。
要避免 KeyError 發(fā)生,有兩個(gè)辦法:
* **一是先判斷一下 key 是否存在,用 in 操作符:**
if 'Paul' in d:
print d['Paul']```
如果 'Paul' 不存在,if語(yǔ)句判斷為False,自然不會(huì)執(zhí)行 print d['Paul'] ,從而避免了錯(cuò)誤。
- 二是使用dict本身提供的一個(gè) get 方法,在Key不存在的時(shí)候,返回None:
>>> print d.get('Bart')
59
>>> print d.get('Paul')
None```
####dict的特點(diǎn)
* **dict的第一個(gè)特點(diǎn)是<font color=#FF4500 >查找速度快 </font>,無(wú)論dict有10個(gè)元素還是10萬(wàn)個(gè)元素,查找速度都一樣**。而list的查找速度隨著元素增加而逐漸下降。
不過(guò)dict的查找速度快不是沒(méi)有代價(jià)的,**dict的缺點(diǎn)是占用內(nèi)存大,還會(huì)浪費(fèi)很多內(nèi)容**,list正好相反,占用內(nèi)存小,但是查找速度慢。
由于dict是按 key 查找,所以,在一個(gè)dict中,key不能重復(fù)。
* **dict的第二個(gè)特點(diǎn)就是存儲(chǔ)的key-value序?qū)κ?lt;font color=#FF4500 >沒(méi)有順序 </font>的!**這和list不一樣:
d = {
'Adam': 95,
'Lisa': 85,
'Bart': 59
}
當(dāng)我們?cè)噲D打印這個(gè)dict時(shí):
print d
{'Lisa': 85, 'Adam': 95, 'Bart': 59}```
打印的順序不一定是我們創(chuàng)建時(shí)的順序,而且,不同的機(jī)器打印的順序都可能不同,這說(shuō)明dict內(nèi)部是無(wú)序的,不能用dict存儲(chǔ)有序的集合。
- dict的第三個(gè)特點(diǎn)是作為 key 的元素必須不可變,Python的基本類型如字符串、整數(shù)、浮點(diǎn)數(shù)都是不可變的,都可以作為 key。但是list是可變的,就不能作為 key。
不可變這個(gè)限制僅作用于key,value是否可變無(wú)所謂:
{
'123': [1, 2, 3], # key 是 str,value是list
123: '123', # key 是 int,value 是 str
('a', 'b'): True # key 是 tuple,并且tuple的每個(gè)元素都是不可變對(duì)象,value是 boolean
}```
最常用的key還是字符串,因?yàn)橛闷饋?lái)最方便。
####什么是set
**dict的作用是建立一組 key 和一組 value 的映射關(guān)系,dict的key是不能重復(fù)的。**
有的時(shí)候,我們只想要 dict 的 key,不關(guān)心 key 對(duì)應(yīng)的 value,目的就是保證這個(gè)集合的元素不會(huì)重復(fù),這時(shí),set就派上用場(chǎng)了。
**set 持有一系列元素,這一點(diǎn)和 list 很像,但是set的元素沒(méi)有重復(fù),而且是無(wú)序的,這點(diǎn)和 dict 的 key很像。**
創(chuàng)建 set 的方式是調(diào)用 set() 并傳入一個(gè) list,list的元素將作為set的元素:
s = set(['A', 'B', 'C'])
可以查看 set 的內(nèi)容:
print s
set(['A', 'C', 'B'])```
注意,上述打印的形式類似 list, 但它不是 list,仔細(xì)看還可以發(fā)現(xiàn),打印的順序和原始 list 的順序有可能是不同的,因?yàn)閟et內(nèi)部存儲(chǔ)的元素是<font color=#FF4500 >無(wú)序</font>的。
因?yàn)?strong><font color=#FF4500 >set不能包含重復(fù)的元素 </font>,所以,當(dāng)我們傳入包含重復(fù)元素的 list 會(huì)怎么樣呢?
>>> s = set(['A', 'B', 'C', 'C'])
>>> print s
set(['A', 'C', 'B'])
>>> len(s)
3
結(jié)果顯示,set會(huì)自動(dòng)去掉重復(fù)的元素,原來(lái)的list有4個(gè)元素,但set只有3個(gè)元素。
訪問(wèn)set
由于set存儲(chǔ)的是無(wú)序集合,所以我們沒(méi)法通過(guò)索引來(lái)訪問(wèn)。
訪問(wèn) set中的某個(gè)元素實(shí)際上就是判斷一個(gè)元素是否在set中。
例如,存儲(chǔ)了班里同學(xué)名字的set:
>>> s = set(['Adam', 'Lisa', 'Bart', 'Paul'])```
**我們可以用 in 操作符判斷:**
Bart是該班的同學(xué)嗎?
'Bart' in s
True```print d
{'Lisa': 85, 'Adam': 95, 'Bart': 59}打印的順序不一定是我們創(chuàng)建時(shí)的順序,而且,不同的機(jī)器打印的順序都可能不同,這說(shuō)明dict內(nèi)部是**無(wú)序**的,不能用dict存儲(chǔ)有序的集合。 * **dict的第三個(gè)特點(diǎn)是作為 key 的元素必須不可變**,Python的基本類型如字符串、整數(shù)、浮點(diǎn)數(shù)都是不可變的,都可以作為 key。但是list是可變的,就不能作為 key。 不可變這個(gè)限制僅作用于key,value是否可變無(wú)所謂:
{
'123': [1, 2, 3], # key 是 str,value是list
123: '123', # key 是 int,value 是 str
('a', 'b'): True # key 是 tuple,并且tuple的每個(gè)元素都是不可變對(duì)象,value是 boolean
}最常用的key還是字符串,因?yàn)橛闷饋?lái)最方便。 ####什么是set **dict的作用是建立一組 key 和一組 value 的映射關(guān)系,dict的key是不能重復(fù)的。** 有的時(shí)候,我們只想要 dict 的 key,不關(guān)心 key 對(duì)應(yīng)的 value,目的就是保證這個(gè)集合的元素不會(huì)重復(fù),這時(shí),set就派上用場(chǎng)了。 **set 持有一系列元素,這一點(diǎn)和 list 很像,但是set的元素沒(méi)有重復(fù),而且是無(wú)序的,這點(diǎn)和 dict 的 key很像。** 創(chuàng)建 set 的方式是調(diào)用 set() 并傳入一個(gè) list,list的元素將作為set的元素:
>>> s = set(['A', 'B', 'C'])
可以查看 set 的內(nèi)容:
>>> print s
set(['A', 'C', 'B'])**注意**,上述打印的形式類似 list, 但它不是 list,仔細(xì)看還可以發(fā)現(xiàn),打印的順序和原始 list 的順序有可能是不同的,因?yàn)閟et內(nèi)部存儲(chǔ)的元素是**<font color=#FF4500 >無(wú)序</font>**的。 因?yàn)?*<font color=#FF4500 >set不能包含重復(fù)的元素 </font>**,所以,當(dāng)我們傳入包含重復(fù)元素的 list 會(huì)怎么樣呢?
>>> s = set(['A', 'B', 'C', 'C'])
>>> print s
set(['A', 'C', 'B'])
>>> len(s)
3
結(jié)果顯示,set會(huì)自動(dòng)去掉重復(fù)的元素,原來(lái)的list有4個(gè)元素,但set只有3個(gè)元素。 ####訪問(wèn)set 由于**set存儲(chǔ)的是無(wú)序集合**,所以我們沒(méi)法通過(guò)索引來(lái)訪問(wèn)。 訪問(wèn) set中的某個(gè)元素實(shí)際上就是判斷一個(gè)元素是否在set中。 例如,存儲(chǔ)了班里同學(xué)名字的set:
>>> s = set(['Adam', 'Lisa', 'Bart', 'Paul'])**我們可以用 in 操作符判斷:** Bart是該班的同學(xué)嗎?
>>> 'Bart' in s
True```
Bill是該班的同學(xué)嗎?
>>> 'Bill' in s
False```
bart是該班的同學(xué)嗎?
'bart' in s
False```
看來(lái)大小寫很重要,'Bart' 和 'bart'被認(rèn)為是兩個(gè)不同的元素
set的特點(diǎn)
set的內(nèi)部結(jié)構(gòu)和dict很像,唯一區(qū)別是不存儲(chǔ)value,因此,判斷一個(gè)元素是否在set中速度很快。
set存儲(chǔ)的元素和dict的key類似,必須是不變對(duì)象,因此,任何可變對(duì)象是不能放入set中的。
最后,<font color=#FF4500 >set存儲(chǔ)的元素也是沒(méi)有順序的 </font>。
set的這些特點(diǎn),可以應(yīng)用在哪些地方呢?
星期一到星期日可以用字符串'MON', 'TUE', ... 'SUN'表示。
假設(shè)我們讓用戶輸入星期一至星期日的某天,如何判斷用戶的輸入是否是一個(gè)有效的星期呢?
可以用** if 語(yǔ)句**判斷,但這樣做非常繁瑣。
如果事先創(chuàng)建好一個(gè)set,包含'MON' ~ 'SUN':
weekdays = set(['MON', 'TUE', 'WED', 'THU', 'FRI', 'SAT', 'SUN'])```
再判斷輸入是否有效,只需要判斷該字符串是否在set中:
x = '???' # 用戶輸入的字符串
if x in weekdays:
print 'input ok'
else:
print 'input error'```
這樣一來(lái),代碼就簡(jiǎn)單多了。
遍歷set
由于 set 也是一個(gè)集合,所以,遍歷 set 和遍歷 list 類似,都可以通過(guò) for 循環(huán)實(shí)現(xiàn)。
直接使用 for 循環(huán)可以遍歷 set 的元素:
>>> s = set(['Adam', 'Lisa', 'Bart'])
>>> for name in s:
.. print name
...
Lisa
Adam
Bart```
**注意: **觀察 for 循環(huán)在遍歷set時(shí),元素的順序和list的順序很可能是不同的,而且不同的機(jī)器上運(yùn)行的結(jié)果也可能不同。
例:用 for 循環(huán)遍歷如下的set,打印出 name: score 來(lái)。
s = set([('Adam', 95), ('Lisa', 85), ('Bart', 59)])```
代碼:
s = set([('Adam', 95), ('Lisa', 85), ('Bart', 59)])
for x in s:
print x[0]+':',x[1]```
打印結(jié)果:
Lisa: 85
Adam: 95
Bart: 59```
更新set
由于set存儲(chǔ)的是一組不重復(fù)的無(wú)序元素,因此,更新set主要做兩件事:
一是把新的元素添加到set中,二是把已有元素從set中刪除。
添加元素時(shí),用set的add()方法:
>>> s = set([1, 2, 3])
>>> s.add(4)
>>> print s
set([1, 2, 3, 4])```
如果添加的元素已經(jīng)存在于set中,add()不會(huì)報(bào)錯(cuò),但是不會(huì)加進(jìn)去了:
s = set([1, 2, 3])
s.add(3)
print s
set([1, 2, 3])```
刪除set中的元素時(shí),用set的<font color=#FF4500 >remove() </font>方法:
>>> s = set([1, 2, 3, 4])
>>> s.remove(4)
>>> print s
set([1, 2, 3])```
如果刪除的元素不存在set中,remove()會(huì)報(bào)錯(cuò):
s = set([1, 2, 3])
s.remove(4)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 4```
所以用add()可以直接添加,而remove()前需要判斷。
函數(shù)
什么是函數(shù)
抽象是數(shù)學(xué)中非常常見(jiàn)的概念。
借助抽象,我們才能不關(guān)心底層的具體計(jì)算過(guò)程,而直接在更高的層次上思考問(wèn)題。
寫計(jì)算機(jī)程序也是一樣,函數(shù)就是最基本的一種代碼抽象的方式。
Python不但能非常靈活地定義函數(shù),而且本身內(nèi)置了很多有用的函數(shù),可以直接調(diào)用。
調(diào)用函數(shù)
Python內(nèi)置了很多有用的函數(shù),我們可以直接調(diào)用。
要調(diào)用一個(gè)函數(shù),需要知道<font color=#FF4500 >函數(shù)的名稱和參數(shù)</font>,比如求絕對(duì)值的函數(shù) abs,它接收一個(gè)參數(shù)。
可以直接從Python的官方網(wǎng)站查看文檔:
http://docs.python.org/2/library/functions.html
#abs
也可以在交互式命令行通過(guò) help(abs)查看abs函數(shù)的幫助信息。
調(diào)用 **abs **函數(shù):
>>> abs(100)
100
>>> abs(-20)
20
>>> abs(12.34)
12.34```
調(diào)用函數(shù)的時(shí)候,如果傳入的參數(shù)數(shù)量不對(duì),會(huì)報(bào)**TypeError**的錯(cuò)誤,并且Python會(huì)明確地告訴你:abs()有且僅有1個(gè)參數(shù),但給出了兩個(gè):
abs(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: abs() takes exactly one argument (2 given)```
如果傳入的參數(shù)數(shù)量是對(duì)的,但參數(shù)類型不能被函數(shù)所接受,也會(huì)報(bào)TypeError的錯(cuò)誤,并且給出錯(cuò)誤信息:str是錯(cuò)誤的參數(shù)類型:
>>> abs('a')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: bad operand type for abs(): 'str'```
而比較函數(shù)**<font color=#FF4500 >cmp(x, y) </font>** 就需要兩個(gè)參數(shù),如果 **x<y**,返回** -1**,如果** x==y**,返回 **0**,如果 **x>y**,返回 **1**:
cmp(1, 2)
-1
cmp(2, 1)
1
cmp(3, 3)
0```
Python內(nèi)置的常用函數(shù)還包括數(shù)據(jù)類型轉(zhuǎn)換函數(shù),比如<font color=#FF4500 > int() </font>函數(shù)可以把其他數(shù)據(jù)類型轉(zhuǎn)換為整數(shù):
>>> int('123')
123
>>> int(12.34)
12```
**<font color=#FF4500 >str()</font>**函數(shù)把其他類型轉(zhuǎn)換成 str:
str(123)
'123'
str(1.23)
'1.23'```
例子:
sum()函數(shù)接受一個(gè)list作為參數(shù),并返回list所有元素之和。請(qǐng)計(jì)算 11 + 22 + 33 + ... + 100100
代碼:
L = [ ]
x=1
while x<=100:
L.append(x*x)
x=x+1
print sum(L)```
打印結(jié)果:
338350```
編寫函數(shù)
在Python中,定義一個(gè)函數(shù)要使用** def 語(yǔ)句,依次寫出函數(shù)名、括號(hào)、括號(hào)中的參數(shù)和冒號(hào):**,然后,在縮進(jìn)塊中編寫函數(shù)體,函數(shù)的返回值用 return語(yǔ)句返回。
例子:定義一個(gè) square_of_sum 函數(shù),它接受一個(gè)list,返回list中每個(gè)元素平方的和。
代碼:
def square_of_sum(L):
sum=0
for x in L:
sum = sum +x**2
return sum
print square_of_sum([1, 2, 3, 4, 5])
print square_of_sum([-5, 0, 5, 15, 25])```
打印結(jié)果:
55
900```
注意,函數(shù)體內(nèi)部的語(yǔ)句在執(zhí)行時(shí),一旦執(zhí)行到return時(shí),函數(shù)就執(zhí)行完畢,并將結(jié)果返回。因此,函數(shù)內(nèi)部通過(guò)條件判斷和循環(huán)可以實(shí)現(xiàn)非常復(fù)雜的邏輯。
如果沒(méi)有return語(yǔ)句,函數(shù)執(zhí)行完畢后也會(huì)返回結(jié)果,只是結(jié)果為 None。
<font color=#FF4500 > return None可以簡(jiǎn)寫為return。 </font>
返回多值
函數(shù)可以返回多個(gè)值嗎?答案是肯定的。
比如在游戲中經(jīng)常需要從一個(gè)點(diǎn)移動(dòng)到另一個(gè)點(diǎn),給出坐標(biāo)、位移和角度,就可以計(jì)算出新的坐標(biāo):
<font color=#FF4500 >#math</font>包提供了sin()和 cos()函數(shù),我們先用import引用它:
import math
def move(x, y, step, angle):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny```
這樣我們就可以同時(shí)獲得返回值:
x, y = move(100, 100, 60, math.pi / 6)
print x, y
cmp(3, 3)
0Python內(nèi)置的常用函數(shù)還包括數(shù)據(jù)類型轉(zhuǎn)換函數(shù),比如**<font color=#FF4500 > int() </font>**函數(shù)可以把其他數(shù)據(jù)類型轉(zhuǎn)換為整數(shù):
>>> int('123')
123
>>> int(12.34)
12**<font color=#FF4500 >str()</font>**函數(shù)把其他類型轉(zhuǎn)換成 str:
>>> str(123)
'123'
>>> str(1.23)
'1.23'例子: sum()函數(shù)接受一個(gè)list作為參數(shù),并返回list所有元素之和。請(qǐng)計(jì)算 1*1 + 2*2 + 3*3 + ... + 100*100 代碼:
L = [ ]
x=1
while x<=100:
L.append(xx)
x=x+1
print sum(L)打印結(jié)果:
338350####編寫函數(shù) 在Python中,定義一個(gè)函數(shù)要使用** def **語(yǔ)句,依次寫出**函數(shù)名**、**括號(hào)**、括號(hào)中的**參數(shù)**和**冒號(hào):**,然后,在縮進(jìn)塊中編寫函數(shù)體,函數(shù)的返回值用 **return**語(yǔ)句返回。 例子:定義一個(gè) square_of_sum 函數(shù),它接受一個(gè)list,返回list中每個(gè)元素平方的和。 代碼:
def square_of_sum(L):
sum=0
for x in L:
sum = sum +x*2
return sum
print square_of_sum([1, 2, 3, 4, 5])
print square_of_sum([-5, 0, 5, 15, 25])打印結(jié)果:
55
900**注意**,函數(shù)體內(nèi)部的語(yǔ)句在執(zhí)行時(shí),一旦執(zhí)行到return時(shí),函數(shù)就執(zhí)行完畢,并將結(jié)果返回。因此,函數(shù)內(nèi)部通過(guò)條件判斷和循環(huán)可以實(shí)現(xiàn)非常復(fù)雜的邏輯。 如果沒(méi)有return語(yǔ)句,函數(shù)執(zhí)行完畢后也會(huì)返回結(jié)果,只是結(jié)果為 None。 **<font color=#FF4500 > return None可以簡(jiǎn)寫為return。 </font>** ####返回多值 函數(shù)可以返回多個(gè)值嗎?答案是肯定的。 比如在游戲中經(jīng)常需要從一個(gè)點(diǎn)移動(dòng)到另一個(gè)點(diǎn),給出坐標(biāo)、位移和角度,就可以計(jì)算出新的坐標(biāo): **<font color=#FF4500 >#math</font>**包提供了**sin()**和 **cos()**函數(shù),我們先用import引用它:
import math
def move(x, y, step, angle):
nx = x + step * math.cos(angle)
ny = y - step * math.sin(angle)
return nx, ny這樣我們就可以同時(shí)獲得返回值:
>>> x, y = move(100, 100, 60, math.pi / 6)
>>> print x, y
151.961524227 70.0```
但其實(shí)這只是一種假象,Python函數(shù)返回的仍然是單一值:
>>> r = move(100, 100, 60, math.pi / 6)
>>> print r
(151.96152422706632, 70.0)```
用print打印返回結(jié)果,原來(lái)返回值是一個(gè)**tuple**!
但是,在語(yǔ)法上,返回一個(gè)tuple可以省略括號(hào),而多個(gè)變量可以同時(shí)接收一個(gè)tuple,按位置賦給對(duì)應(yīng)的值,所以,**Python的函數(shù)**返回多值其實(shí)就是**返回一個(gè)tuple**,但寫起來(lái)更方便。
例子:
一元二次方程的定義是:ax2 + bx + c = 0
請(qǐng)編寫一個(gè)函數(shù),返回一元二次方程的兩個(gè)解。
**注意:**Python的math包提供了sqrt()函數(shù)用于計(jì)算平方根。
代碼:
import math
def quadratic_equation(a, b, c):
de=b2-4ac
if de>=0:
x1=(-b+math.sqrt(b2-4ac))/(2a)
x2=(-b-math.sqrt(b2-4ac))/(2a)
return x1,x2
else:
return
print quadratic_equation(2, 3, 0)
print quadratic_equation(1, -6, 5)```
打印結(jié)果:
(0.0, -1.5)
(5.0, 1.0)```
####遞歸函數(shù)
在函數(shù)內(nèi)部,可以調(diào)用其他函數(shù)。如果一個(gè)函數(shù)在內(nèi)部調(diào)用自身本身,這個(gè)函數(shù)就是遞歸函數(shù)。
舉個(gè)例子,我們來(lái)計(jì)算階乘 **n! = 1 * 2 * 3 * ... * n**,用函數(shù) **fact(n)**表示,可以看出:
fact(n) = n! = 1 * 2 * 3 * ... * (n-1) * n = (n-1)! * n = fact(n-1) * n```
所以,fact(n)可以表示為 n * fact(n-1),只有n=1時(shí)需要特殊處理。
于是,fact(n)用遞歸的方式寫出來(lái)就是:
def fact(n):
if n==1:
return 1
return n * fact(n - 1)```
如果我們計(jì)算fact(5),可以根據(jù)函數(shù)定義看到計(jì)算過(guò)程如下:
===> fact(5)
===> 5 * fact(4)
===> 5 * (4 * fact(3))
===> 5 * (4 * (3 * fact(2)))
===> 5 * (4 * (3 * (2 * fact(1))))
===> 5 * (4 * (3 * (2 * 1)))
===> 5 * (4 * (3 * 2))
===> 5 * (4 * 6)
===> 5 * 24
===> 120```
遞歸函數(shù)的優(yōu)點(diǎn)是定義簡(jiǎn)單,邏輯清晰。理論上,所有的遞歸函數(shù)都可以寫成循環(huán)的方式,但循環(huán)的邏輯不如遞歸清晰。
<font color=#FF4500 >使用遞歸函數(shù)需要注意防止棧溢出。</font>在計(jì)算機(jī)中,函數(shù)調(diào)用是通過(guò)棧(stack)這種數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)的,每當(dāng)進(jìn)入一個(gè)函數(shù)調(diào)用,棧就會(huì)加一層棧幀,每當(dāng)函數(shù)返回,棧就會(huì)減一層棧幀。由于棧的大小不是無(wú)限的,所以,遞歸調(diào)用的次數(shù)過(guò)多,會(huì)導(dǎo)致棧溢出。
例子:
漢諾(http://baike.baidu.com/view/191666.htm) 的移動(dòng)也可以看做是遞歸函數(shù)。
我們對(duì)柱子編號(hào)為a, b, c,將所有圓盤從a移到c可以描述為:
如果a只有一個(gè)圓盤,可以直接移動(dòng)到c;
如果a有N個(gè)圓盤,可以看成a有1個(gè)圓盤(底盤) + (N-1)個(gè)圓盤,首先需要把 (N-1) 個(gè)圓盤移動(dòng)到 b,然后,將 a的最后一個(gè)圓盤移動(dòng)到c,再將b的(N-1)個(gè)圓盤移動(dòng)到c。
請(qǐng)編寫一個(gè)函數(shù),給定輸入 n, a, b, c,打印出移動(dòng)的步驟:
move(n, a, b, c)
例如,輸入 move(2, 'A', 'B', 'C'),打印出:
A --> B
A --> C
B --> C
代碼:
#-*- coding:utf-8 -*-
# move(n, a, b, c)表示的是有n個(gè)盤子在a柱子上,將要移到c柱子上面去
def move(n, a, b, c):
# 如果a柱子上面只有一個(gè)盤子,則直接移到c柱子上面去并輸出路徑,結(jié)束遞歸
if n == 1:
print a, '-->', c
return
# 表示的是將n-1的盤子從a柱子上面移到b柱子上面去
move(n-1, a, c, b)
# 輸出最下面?zhèn)€盤子移從a移到c的路徑
print a, '-->', c
# 將b柱子上面的n-1個(gè)盤子移動(dòng)到c柱子上面
move(n-1, b, a, c)
move(4, 'A', 'B', 'C')```
打印結(jié)果:
A --> B
A --> C
B --> C
A --> B
C --> A
C --> B
A --> B
A --> C
B --> C
B --> A
C --> A
B --> C
A --> B
A --> C
B --> C```
定義默認(rèn)參數(shù)
定義函數(shù)的時(shí)候,還可以有默認(rèn)參數(shù)。
例如Python自帶的 int() 函數(shù),其實(shí)就有兩個(gè)參數(shù),我們既可以傳一個(gè)參數(shù),又可以傳兩個(gè)參數(shù):
>>> int('123')
123
>>> int('123', 8)
83```
int()函數(shù)的第二個(gè)參數(shù)是轉(zhuǎn)換進(jìn)制,如果不傳,默認(rèn)是十進(jìn)制 (base=10),如果傳了,就用傳入的參數(shù)。
可見(jiàn),**函數(shù)的默認(rèn)參數(shù)的作用是簡(jiǎn)化調(diào)用**,你只需要把必須的參數(shù)傳進(jìn)去。但是在需要的時(shí)候,又可以傳入額外的參數(shù)來(lái)覆蓋默認(rèn)參數(shù)值。
我們來(lái)定義一個(gè)計(jì)算 x 的N次方的函數(shù):
def power(x, n):
s = 1
while n > 0:
n = n - 1
s = s * x
return s```
假設(shè)計(jì)算平方的次數(shù)最多,我們就可以把 n 的默認(rèn)值設(shè)定為 2:
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s```
這樣一來(lái),計(jì)算平方就不需要傳入兩個(gè)參數(shù)了:
power(5)
25
由于函數(shù)的參數(shù)按從左到右的順序匹配,所以**默認(rèn)參數(shù)只能定義在必需參數(shù)的后面:**
OK:
def fn1(a, b=1, c=2):
pass
Error:
def fn2(a=1, b):
pass```
例子:
定義一個(gè) greet() 函數(shù),它包含一個(gè)默認(rèn)參數(shù),如果沒(méi)有傳入,打印 'Hello, world.',如果傳入,打印 'Hello, xxx.'默認(rèn)參數(shù)的默認(rèn)值可以設(shè)定為'world'
代碼:
def greet(name='world'):
print 'Hello, ' + name + '.'
greet()
greet('Bart')```
打印結(jié)果:
Hello,world.
Hello,Bart.```
定義可變參數(shù)
如果想讓一個(gè)函數(shù)能接受任意個(gè)參數(shù),我們就可以定義一個(gè)可變參數(shù):
def fn(*args):
print args```
可變參數(shù)的名字前面有個(gè) *** **號(hào),我們可以傳入0個(gè)、1個(gè)或多個(gè)參數(shù)給可變參數(shù):
fn()
()
fn('a')
('a',)
fn('a', 'b')
('a', 'b')
fn('a', 'b', 'c')
('a', 'b', 'c')```
可變參數(shù)也不是很神秘,Python解釋器會(huì)把傳入的一組參數(shù)組裝成一個(gè)tuple傳遞給可變參數(shù),因此,在函數(shù)內(nèi)部,直接把變量** args** 看成一個(gè) tuple 就好了。
定義可變參數(shù)的目的也是為了簡(jiǎn)化調(diào)用。假設(shè)我們要計(jì)算任意個(gè)數(shù)的平均值,就可以定義一個(gè)可變參數(shù):
def average(*args):
...```
這樣,在調(diào)用的時(shí)候,可以這樣寫:
average()
0
average(1, 2)
1.5
average(1, 2, 2, 3, 4)
2.4```
例子:
編寫接受可變參數(shù)的 average() 函數(shù)。
可變參數(shù) args 是一個(gè)tuple,當(dāng)0個(gè)參數(shù)傳入時(shí),args是一個(gè)空tuple。
代碼:
def average(*args):
sum = 0.0
if len(args) == 0:
return sum
for x in args:
sum = sum + x
return sum / len(args)
print average()
print average(1, 2)
print average(1, 2, 2, 3, 4)```
打印結(jié)果:
0.0
1.5
2.4```
切片
對(duì)list進(jìn)行切片
取一個(gè)list的部分元素是非常常見(jiàn)的操作。比如,一個(gè)list如下:
>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']```
取前N個(gè)元素,也就是索引為0-(N-1)的元素,可以用循環(huán),對(duì)這種經(jīng)常取指定索引范圍的操作,用循環(huán)十分繁瑣,因此,Python提供了切片(Slice)操作符,能大大簡(jiǎn)化這種操作。
對(duì)應(yīng)上面的問(wèn)題,取前3個(gè)元素,用一行代碼就可以完成切片:
L[0:3]
['Adam', 'Lisa', 'Bart']```
L[0:3]表示,從索引0開(kāi)始取,直到索引3為止,但不包括索引3。即索引0,1,2,正好是3個(gè)元素。
如果第一個(gè)索引是0,還可以省略:
>>> L[:3]
['Adam', 'Lisa', 'Bart']```
也可以從索引1開(kāi)始,取出2個(gè)元素出來(lái):
L[1:3]
['Lisa', 'Bart']```
只用一個(gè)** : **,表示從頭到尾:
>>> L[:]
['Adam', 'Lisa', 'Bart', 'Paul']```
**因此,L[:]實(shí)際上復(fù)制出了一個(gè)新list。**
切片操作還可以指定第三個(gè)參數(shù):
L[::2]
['Adam', 'Bart']```
第三個(gè)參數(shù)表示每N個(gè)取一個(gè),上面的 L[::2] 會(huì)每?jī)蓚€(gè)元素取出一個(gè)來(lái),也就是隔一個(gè)取一個(gè)。
把list換成tuple,切片操作完全相同,只是切片的結(jié)果也變成了tuple。
例子:
range()函數(shù)可以創(chuàng)建一個(gè)數(shù)列:
>>> range(1, 101)
[1, 2, 3, ..., 100]```
請(qǐng)利用切片,取出:
1. 前10個(gè)數(shù);
2. 3的倍數(shù);
3. 不大于50的5的倍數(shù)。
代碼:
L = range(1, 101)
print L[0:10]
print L[2::3]
print L[4:50:5]
打印結(jié)果:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
[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]
[5, 10, 15, 20, 25, 30, 35, 40, 45, 50]```
倒序切片
對(duì)于list,既然Python支持L[-1]取倒數(shù)第一個(gè)元素,那么它同樣支持倒數(shù)切片,試試:
>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
>>> L[-2:]
['Bart', 'Paul']
>>> L[:-2]
['Adam', 'Lisa']
>>> L[-3:-1]
['Lisa', 'Bart']
>>> L[-4:-1:2]
['Adam', 'Bart']```
記住倒數(shù)第一個(gè)元素的索引是-1。
**倒序切片包含起始索引,不包含結(jié)束索引。**
####對(duì)字符串切片
字符串 'xxx'和 Unicode字符串 u'xxx'也可以看成是一種**list**,每個(gè)元素就是一個(gè)字符。因此,字符串也可以用切片操作,只是操作結(jié)果仍是字符串:
'ABCDEFG'[:3]
'ABC'
'ABCDEFG'[-3:]
'EFG'
'ABCDEFG'[::2]
'ACEG'```
在很多編程語(yǔ)言中,針對(duì)字符串提供了很多各種截取函數(shù),其實(shí)目的就是對(duì)字符串切片。Python沒(méi)有針對(duì)字符串的截取函數(shù),只需要切片一個(gè)操作就可以完成,非常簡(jiǎn)單。
例子:
字符串有個(gè)方法 upper() 可以把字符變成大寫字母:
>>> 'abc'.upper()
'ABC'```
但它會(huì)把所有字母都變成大寫。請(qǐng)?jiān)O(shè)計(jì)一個(gè)函數(shù),它接受一個(gè)字符串,然后返回一個(gè)僅首字母變成大寫的字符串。
**提示:**利用切片操作簡(jiǎn)化字符串操作。
代碼:
def firstCharUpper(s):
return s[0].upper()+s[1:]
print firstCharUpper('hello')
print firstCharUpper('sunday')
print firstCharUpper('september')```
打印結(jié)果:
Hello
Sunday
September```
###迭代
####什么是迭代
在Python中,如果給定一個(gè)**list**或**tuple**,我們可以通過(guò)for循環(huán)來(lái)遍歷這個(gè)list或tuple,這種遍歷我們成為迭代(Iteration)。
在Python中,迭代是通過(guò) for ... in 來(lái)完成的,而很多語(yǔ)言比如C或者Java,迭代list是通過(guò)下標(biāo)完成的,比如Java代碼:
for (i=0; i<list.length; i++) {
n = list[i];
}
可以看出,Python的for循環(huán)抽象程度要高于Java的for循環(huán)。
**因?yàn)?Python 的 for循環(huán)不僅可以用在list或tuple上,還可以作用在其他任何可迭代對(duì)象上。**
因此,迭代操作就是對(duì)于一個(gè)集合,無(wú)論該集合是有序還是無(wú)序,我們用 for 循環(huán)總是可以依次取出集合的每一個(gè)元素。
注意: 集合是指包含一組元素的數(shù)據(jù)結(jié)構(gòu),我們已經(jīng)介紹的包括:
- 有序集合:list,tuple,str和unicode;
- 無(wú)序集合:set
- 無(wú)序集合并且具有 key-value 對(duì):dict```
而迭代是一個(gè)動(dòng)詞,它指的是一種操作,在Python中,就是 for 循環(huán)。
迭代與按下標(biāo)訪問(wèn)數(shù)組最大的不同是,后者是一種具體的迭代實(shí)現(xiàn)方式,而前者只關(guān)心迭代結(jié)果,根本不關(guān)心迭代內(nèi)部是如何實(shí)現(xiàn)的。
例子:
用for循環(huán)迭代數(shù)列 1-100 并打印出7的倍數(shù)
代碼:
for i in range(1,101):
if i %7 == 0:
print i```
打印結(jié)果:
7
14
21
28
35
42
49
56
63
70
77
84
91
98```
索引迭代
Python中,迭代永遠(yuǎn)是取出元素本身,而非元素的索引。
對(duì)于有序集合,元素確實(shí)是有索引的。有的時(shí)候,我們確實(shí)想在 for 循環(huán)中拿到索引,怎么辦?
方法是使用 enumerate() 函數(shù):
>>> L = ['Adam', 'Lisa', 'Bart', 'Paul']
>>> for index, name in enumerate(L):
... print index, '-', name
...
0 - Adam
1 - Lisa
2 - Bart
4 - Paul```
使用 enumerate() 函數(shù),我們可以在for循環(huán)中同時(shí)綁定索引index和元素name。但是,這不是 enumerate() 的特殊語(yǔ)法。實(shí)際上,enumerate() 函數(shù)把:
['Adam', 'Lisa', 'Bart', 'Paul']```
變成了類似:
**[(0, 'Adam'), (1, 'Lisa'), (2, 'Bart'), (3, 'Paul')]**```
因此,迭代的每一個(gè)元素實(shí)際上是一個(gè)tuple:
for t in enumerate(L):
index = t[0]
name = t[1]
print index, '-', name```
如果我們知道每個(gè)tuple元素都包含兩個(gè)元素,for循環(huán)又可以進(jìn)一步簡(jiǎn)寫為:
for index, name in enumerate(L):
print index, '-', name```
這樣不但代碼更簡(jiǎn)單,而且還少了兩條賦值語(yǔ)句。
可見(jiàn),索引迭代也不是真的按索引訪問(wèn),而是由 enumerate() 函數(shù)自動(dòng)把每個(gè)元素變成 (index, element) 這樣的tuple,再迭代,就同時(shí)獲得了索引和元素本身。
例子:
zip()函數(shù)可以把兩個(gè) list 變成一個(gè) list:
zip([10, 20, 30], ['A', 'B', 'C'])[(10, 'A'), (20, 'B'), (30, 'C')]```
在迭代 ['Adam', 'Lisa', 'Bart', 'Paul'] 時(shí),如果我們想打印出名次 - 名字(名次從1開(kāi)始),請(qǐng)考慮如何在迭代中打印出來(lái)。
提示:考慮使用zip()函數(shù)和range()函數(shù)
代碼:
L = ['Adam', 'Lisa', 'Bart', 'Paul']
for index, name in zip(range(1,len(L)+1),L):
print index,'-',name```
打印結(jié)果:
1 - Adam
2 - Lisa
3 - Bart
4 - Paul```
迭代dict的value
我們已經(jīng)了解了dict對(duì)象本身就是可迭代對(duì)象,用 for 循環(huán)直接迭代 dict,可以每次拿到dict的一個(gè)key。
如果我們希望迭代 dict 對(duì)象的value,應(yīng)該怎么做?
dict 對(duì)象有一個(gè) values() 方法,這個(gè)方法把dict轉(zhuǎn)換成一個(gè)包含所有value的list,這樣,我們迭代的就是 dict的每一個(gè) value:
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print d.values()
# [85, 95, 59]
for v in d.values():
print v
# 85
# 95
# 59
如果仔細(xì)閱讀Python的文檔,還可以發(fā)現(xiàn),dict除了values()方法外,還有一個(gè)** itervalues() 方法,用 itervalues()** 方法替代 values()方法,迭代效果完全一樣:
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print d.itervalues()
# <dictionary-valueiterator object at 0x106adbb50>
for v in d.itervalues():
print v
# 85
# 95
# 59```
**那這兩個(gè)方法有何不同之處呢?**
1. **values()** 方法實(shí)際上把一個(gè) dict 轉(zhuǎn)換成了包含 value 的list。
2. 但是 **itervalues()** 方法不會(huì)轉(zhuǎn)換,它會(huì)在迭代過(guò)程中依次從 dict 中取出 value,所以 itervalues() 方法比 values() 方法節(jié)省了生成 list 所需的內(nèi)存。
3. 打印 itervalues() 發(fā)現(xiàn)它返回一個(gè) <dictionary-valueiterator> 對(duì)象,這說(shuō)明在Python中,**for 循環(huán)可作用的迭代對(duì)象遠(yuǎn)不止 list,tuple,str,unicode,dict等**,任何可迭代對(duì)象都可以作用于for循環(huán),而內(nèi)部如何迭代我們通常并不用關(guān)心。
**如果一個(gè)對(duì)象說(shuō)自己可迭代,那我們就直接用 for 循環(huán)去迭代它,可見(jiàn),迭代是一種抽象的數(shù)據(jù)操作,它不對(duì)迭代對(duì)象內(nèi)部的數(shù)據(jù)有任何要求。**
####迭代dict的key和value
我們了解了如何**迭代 dict** 的**key**和**value**,那么,在一個(gè) for 循環(huán)中,能否同時(shí)迭代 key和value?答案是肯定的。
首先,我們看看 dict 對(duì)象的 **items()** 方法返回的值:
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
print d.items()
[('Lisa', 85), ('Adam', 95), ('Bart', 59)]```
可以看到,items() 方法把dict對(duì)象轉(zhuǎn)換成了包含tuple的list,我們對(duì)這個(gè)list進(jìn)行迭代,可以同時(shí)獲得key和value:
>>> for key, value in d.items():
... print key, ':', value
...
Lisa : 85
Adam : 95
Bart : 59```
和 values() 有一個(gè) itervalues() 似, **items() **也有一個(gè)對(duì)應(yīng)的 **iteritems()**,iteritems() 不把dict轉(zhuǎn)換成list,而是在迭代過(guò)程中不斷給出 tuple,所以, iteritems() 不占用額外的內(nèi)存。
###列表生成式
####生成列表
要生成list [1, 2, 3, 4, 5, 6, 7, 8, 9, 10],我們可以用range(1, 11):
range(1, 11)
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]```
但如果要生成[1x1, 2x2, 3x3, ..., 10x10]怎么做?方法一是循環(huán):
>>> L = []
>>> for x in range(1, 11):
... L.append(x * x)
...
>>> L
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]```
但是循環(huán)太繁瑣,而列表生成式則可以用一行語(yǔ)句代替循環(huán)生成上面的list:
[x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]```
這種寫法就是Python特有的列表生成式。利用列表生成式,可以以非常簡(jiǎn)潔的代碼生成 list。
寫列表生成式時(shí),把要生成的元素 x * x 放到前面,后面跟 for 循環(huán),就可以把list創(chuàng)建出來(lái),十分有用,多寫幾次,很快就可以熟悉這種語(yǔ)法。
注意:range(1, 100, 2) 可以生成list [1, 3, 5, 7, 9,...]
復(fù)雜表達(dá)式
使用for循環(huán)的迭代不僅可以迭代普通的list,還可以迭代dict。
假設(shè)有如下的dict:
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }```
完全可以通過(guò)一個(gè)復(fù)雜的列表生成式把它變成一個(gè) HTML 表格:
tds = ['<tr><td>%s</td><td>%s</td></tr>' % (name, score) for name, score in d.iteritems()]
print '<table>'
print '<tr><th>Name</th><th>Score</th><tr>'
print '\n'.join(tds)
print '</table>'```
注:字符串可以通過(guò) % 進(jìn)行格式化,用指定的參數(shù)替代** **%s。字符串的join()方法可以把一個(gè) list 拼接成一個(gè)字符串。
把打印出來(lái)的結(jié)果保存為一個(gè)html文件,就可以在瀏覽器中看到效果了:
<table border="1">
<tr><th>Name</th><th>Score</th><tr>
<tr><td>Lisa</td><td>85</td></tr>
<tr><td>Adam</td><td>95</td></tr>
<tr><td>Bart</td><td>59</td></tr>
</table>```
[](http://img.mukewang.com/540fcd2a0001ff4600940104.jpg)
####條件過(guò)濾
列表生成式的 **for 循環(huán)后面還可以加上 if 判斷**。例如:
[x * x for x in range(1, 11)]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]```
如果我們只想要偶數(shù)的平方,不改動(dòng) range()的情況下,可以加上 if 來(lái)篩選:
>>> [x * x for x in range(1, 11) if x % 2 == 0]
[4, 16, 36, 64, 100]```
有了 if 條件,只有 if 判斷為 True 的時(shí)候,才把循環(huán)的當(dāng)前元素添加到列表中。
例子:
編寫一個(gè)函數(shù),它接受一個(gè) list,然后把list中所有字符串變成大寫后返回,非字符串元素將被忽略。
**提示:**
1. **isinstance(x, str)** 可以判斷變量 x 是否是字符串;
2. 字符串的 **upper()** 方法可以返回大寫的字母
代碼:
def toUppers(L):
return[x.upper()for x in L if isinstance(x,str)]
print toUppers(['Hello', 'world', 101])
打印結(jié)果:
['HELLO', 'WORLD']```
多層表達(dá)式
for循環(huán)可以嵌套,因此,在列表生成式中,也可以用多層 for 循環(huán)來(lái)生成列表。
對(duì)于字符串 'ABC' 和 '123',可以使用兩層循環(huán),生成全排列:
>>> [m + n for m in 'ABC' for n in '123']
['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'C1', 'C2', 'C3']```
翻譯成循環(huán)代碼就像下面這樣:
L = []
for m in 'ABC':
for n in '123':
L.append(m + n)```
例子:
利用 3 層for循環(huán)的列表生成式,找出對(duì)稱的 3 位數(shù)。例如,121 就是對(duì)稱數(shù),因?yàn)閺挠业阶蟮惯^(guò)來(lái)還是 121。
代碼:
print [100 * n1 + 10 * n2 + n3 for n1 in range(1, 10) for n2 in range(10) for n3 in range(10) if n1==n3]```
打印結(jié)果:
[101, 111, 121, 131, 141, 151, 161, 171, 181, 191, 202, 212, 222, 232, 242, 252, 262, 272, 282, 292, 303, 313, 323,
333, 343, 353, 363, 373, 383, 393, 404, 414, 424, 434, 444, 454, 464, 474, 484, 494, 505, 515, 525, 535, 545, 555,
565, 575, 585, 595, 606, 616, 626, 636, 646, 656, 666, 676, 686, 696, 707, 717, 727, 737, 747, 757, 767, 777, 787,
797, 808, 818, 828, 838, 848, 858, 868, 878, 888, 898, 909, 919, 929, 939, 949, 959, 969, 979, 989, 999]```