數(shù)據(jù)類型已經(jīng)學(xué)的差不多了,但是,到現(xiàn)在為止我們還不能真正的寫程序,這就好比小學(xué)生學(xué)習(xí)寫作一樣,到目前為止僅僅學(xué)會(huì)了一些詞語,還不知道如何造句子。從現(xiàn)在開始就學(xué)習(xí)如何造句子了。
在編程語言中,句子被稱之為“語句”,
事實(shí)上,前面已經(jīng)用過語句了,最典型的那句:print "Hello, World"
就是語句。
為了能夠嚴(yán)謹(jǐn)?shù)仃U述這個(gè)概念,抄一段維基百科中的詞條:命令式編程
命令式編程(英語:Imperative programming),是一種描述電腦所需作出的行為的編程范型。幾乎所有電腦的硬件工作都是指令式的;幾乎所有電腦的硬件都是設(shè)計(jì)來運(yùn)行機(jī)器碼,使用指令式的風(fēng)格來寫的。較高級(jí)的指令式編程語言使用變量和更復(fù)雜的語句,但仍依從相同的范型。
運(yùn)算語句一般來說都表現(xiàn)了在存儲(chǔ)器內(nèi)的數(shù)據(jù)進(jìn)行運(yùn)算的行為,然后將結(jié)果存入存儲(chǔ)器中以便日后使用。高級(jí)命令式編程語言更能處理復(fù)雜的表達(dá)式,可能會(huì)產(chǎn)生四則運(yùn)算和函數(shù)計(jì)算的結(jié)合。
一般所有高級(jí)語言,都包含如下語句,Python也不例外:
循環(huán)、條件分支和無條件分支都是控制流程。
當(dāng)然,python中的語句還是有python特別之處的(別的語言中,也會(huì)有自己的特色)。下面就開始娓娓道來。
在python2.x中,print是一個(gè)語句,但是在python3.x中它是一個(gè)函數(shù)了。這點(diǎn)請(qǐng)注意。不過,這里所使用的還是python2.x。
為什么不用python3.x?這個(gè)問題在開始就回答過。但是還有朋友問。重復(fù)回答:因?yàn)楝F(xiàn)在很多工程項(xiàng)目都是python2.x,python3.x相對(duì)python2.x有不完全兼容的地方。學(xué)python的目的就是要在真實(shí)的工程項(xiàng)目中使用,理所應(yīng)當(dāng)要學(xué)python2.x。此外,學(xué)會(huì)了python2.x,將來過渡到python3.x,只需要注意一些細(xì)節(jié)即可。
print發(fā)起的語句,在程序中主要是將某些東西打印出來,還記得在講解字符串的時(shí)候,專門講述了字符串的格式化輸出嗎?那就是用來print的。
>>> print "hello, world"
hello, world
>>> print "hello","world"
hello world
請(qǐng)仔細(xì)觀察,上面兩個(gè)print語句的差別。第一個(gè)打印的是"hello, world",包括其中的逗號(hào)和空格,是一個(gè)完整的字符串。第二個(gè)打印的是兩個(gè)字符串,一個(gè)是"hello",另外一個(gè)是"world",兩個(gè)字符串之間用逗號(hào)分隔。
本來,在print語句中,字符串后面會(huì)接一個(gè)\n
符號(hào)。即換行。但是,如果要在一個(gè)字符串后面跟著逗號(hào),那么換行就取消了,意味著兩個(gè)字符串"hello","world"打印在同一行。
或許現(xiàn)在體現(xiàn)的還不時(shí)很明顯,如果換一個(gè)方法,就顯示出來了。(下面用到了一個(gè)被稱之為循環(huán)的語句,下一節(jié)會(huì)重點(diǎn)介紹。
>>> for i in [1,2,3,4,5]:
... print i
...
1
2
3
4
5
這個(gè)循環(huán)的意思就是要從列表中依次取出每個(gè)元素,然后賦值給變量i,并用print語句打印打出來。在變量i后面沒有任何符號(hào),每打印一個(gè),就換行,再打印另外一個(gè)。
下面的方式就跟上面的有點(diǎn)區(qū)別了。
>>> for i in [1,2,3,4,5]:
... print i ,
...
1 2 3 4 5
就是在print語句的最后加了一個(gè)逗號(hào),打印出來的就在一行了。
print語句經(jīng)常用在調(diào)試程序的過程,讓我們能夠知道程序在執(zhí)行過程中產(chǎn)生的結(jié)果。
在《常用數(shù)學(xué)函數(shù)和運(yùn)算優(yōu)先級(jí)》中,曾經(jīng)用到過一個(gè)math模塊,它能提供很多數(shù)學(xué)函數(shù),但是這些函數(shù)不是python的內(nèi)建函數(shù),是math模塊的,所以,要用import引用這個(gè)模塊。
這種用import引入模塊的方法,是python編程經(jīng)常用到的。引用方法有如下幾種:
>>> import math
>>> math.pow(3,2)
9.0
這是常用的一種方式,而且非常明確,math.pow(3,2)
就明確顯示了,pow()函數(shù)是math模塊里的??梢哉f這是一種可讀性非常好的引用方式,并且不同模塊的同名函數(shù)不會(huì)產(chǎn)生沖突。
>>> from math import pow
>>> pow(3,2)
9.0
這種方法就有點(diǎn)偷懶了,不過也不難理解,從字面意思就知道pow()函數(shù)來自于math模塊。在后續(xù)使用的時(shí)候,只需要直接使用pow()
即可,不需要在前面寫上模塊名稱了。這種引用方法,比較適合于引入模塊較少的時(shí)候。如果引入模塊多了,可讀性就下降了,會(huì)不知道那個(gè)函數(shù)來自那個(gè)模塊。
>>> from math import pow as pingfang
>>> pingfang(3,2)
9.0
這是在前面那種方式基礎(chǔ)上的發(fā)展,將從某個(gè)模塊引入的函數(shù)重命名,比如講pow充命名為pingfang,然后使用pingfang()
就相當(dāng)于在使用pow()
了。
如果要引入多個(gè)函數(shù),可以這樣做:
>>> from math import pow, e, pi
>>> pow(e,pi)
23.140692632779263
引入了math模塊里面的pow,e,pi,pow()是一個(gè)乘方函數(shù),e,就是那個(gè)歐拉數(shù);pi就是π.
e,作為數(shù)學(xué)常數(shù),是自然對(duì)數(shù)函數(shù)的底數(shù)。有時(shí)稱它為歐拉數(shù)(Euler's number),以瑞士數(shù)學(xué)家歐拉命名;也有個(gè)較鮮見的名字納皮爾常數(shù),以紀(jì)念蘇格蘭數(shù)學(xué)家約翰·納皮爾引進(jìn)對(duì)數(shù)。它是一個(gè)無限不循環(huán)小數(shù)。e = 2.71828182845904523536(《維基百科》)
e的π次方,是一個(gè)數(shù)學(xué)常數(shù)。與e和π一樣,它是一個(gè)超越數(shù)。這個(gè)常數(shù)在希爾伯特第七問題中曾提到過。(《維基百科》)
>>> from math import *
>>> pow(3,2)
9.0
>>> sqrt(9)
3.0
這種引入方式是最貪圖省事的了,一下將math中的所有函數(shù)都引過來了。不過,這種方式的結(jié)果是讓可讀性更降低了。僅適用于模塊中的函數(shù)比較少的時(shí)候,并且在程序中應(yīng)用比較頻繁。
在這里,我們用math模塊為例,引入其中的函數(shù)。事實(shí)上,不僅函數(shù)可以引入,模塊中還可以包括常數(shù)等,都可以引入。在編程中,模塊中可以包括各樣的對(duì)象,都可以引入。
對(duì)于賦值語句,應(yīng)該不陌生,在前面已經(jīng)頻繁使用了,如a = 3
這樣的,就是將一個(gè)整數(shù)賦給了變量。
編程中的“=”和數(shù)學(xué)中的“=”是完全不同的。在編程語言中,“=”表示賦值過程。
除了那種最簡(jiǎn)單的賦值之外,還可以這么干:
>>> x, y, z = 1, "python", ["hello", "world"]
>>> x
1
>>> y
'python'
>>> z
['hello', 'world']
這里就一一對(duì)應(yīng)賦值了。如果把幾個(gè)值賦給一個(gè),可以嗎?
>>> a = "itdiffer.com", "python"
>>> a
('itdiffer.com', 'python')
原來是將右邊的兩個(gè)值裝入了一個(gè)元組,然后將元組賦給了變量a。這個(gè)python太聰明了。
在python的賦值語句中,還有一個(gè)更聰明的,它一出場(chǎng),簡(jiǎn)直是讓一些已經(jīng)學(xué)習(xí)過某種其它語言的人亮瞎眼。
有兩個(gè)變量,其中a = 2
,b = 9
?,F(xiàn)在想讓這兩個(gè)變量的值對(duì)調(diào),即最終是a = 9
,b = 2
.
這是一個(gè)簡(jiǎn)單而經(jīng)典的題目。在很多編程語言中,是這么處理的:
temp = a;
a = b;
b = temp;
這么做的那些編程語言,變量就如同一個(gè)盒子,值就如同放到盒子里面的東西。如果要實(shí)現(xiàn)對(duì)調(diào),必須在找一個(gè)盒子,將a盒子里面的東西(數(shù)字2)拿到那個(gè)臨時(shí)盒子(temp)中,這樣a盒子就空了,然后將b盒子中的東西拿(數(shù)字9)拿到a盒子中(a = b),完成這步之后,b盒子是空的了,最后將臨時(shí)盒子里面的那個(gè)數(shù)字2拿到b盒子中。這就實(shí)現(xiàn)了兩個(gè)變量值得對(duì)調(diào)。
太啰嗦了。
python只要一行就完成了。
>>> a = 2
>>> b = 9
>>> a, b = b, a
>>> a
9
>>> b
2
a, b = b, a
就實(shí)現(xiàn)了數(shù)值對(duì)調(diào),多么神奇。之所以神奇,就是因?yàn)槲仪懊嬉呀?jīng)數(shù)次提到的python中變量和數(shù)據(jù)對(duì)象的關(guān)系。變量相當(dāng)于貼在對(duì)象上的標(biāo)簽。這個(gè)操作只不過是將標(biāo)簽換個(gè)位置,就分別指向了不同的數(shù)據(jù)對(duì)象。
還有一種賦值方式,被稱為“鏈?zhǔn)劫x值”
>>> m = n = "I use python"
>>> print m,n
I use python I use python
用這種方式,實(shí)現(xiàn)了一次性對(duì)兩個(gè)變量賦值,并且值相同。
>>> id(m)
3072659528L
>>> id(n)
3072659528L
用id()
來檢查一下,發(fā)現(xiàn)兩個(gè)變量所指向的是同一個(gè)對(duì)象。
另外,還有一種判斷方法,來檢查兩個(gè)變量所指向的值是否是同一個(gè)(注意,同一個(gè)和相等是有差別的。在編程中,同一個(gè)就是id()
的結(jié)果一樣。
>>> m is n
True
這是在檢查m和n分別指向的對(duì)象是否是同一個(gè),True說明是同一個(gè)。
>>> a = "I use python"
>>> b = a
>>> a is b
True
這是跟上面鏈?zhǔn)劫x值等效的。
但是:
>>> b = "I use python"
>>> a is b
False
>>> id(a)
3072659608L
>>> id(b)
3072659568L
>>> a == b
True
看出其中的端倪了嗎?這次a、b兩個(gè)變量雖然相等,但不是指向同一個(gè)對(duì)象。
還有一種賦值形式,如果從數(shù)學(xué)的角度看,是不可思議的,如:x = x + 1
,在數(shù)學(xué)中,這個(gè)等式是不成立的。因?yàn)閿?shù)學(xué)中的“=”是等于的含義,但是在編程語言中,它成立,因?yàn)?="是賦值的含義,即將變量x增加1之后,再把得到的結(jié)果賦值變量x.
這種變量自己變化之后將結(jié)果再賦值給自己的形式,稱之為“增量賦值”。+、-、*、/、%都可以實(shí)現(xiàn)這種操作。
為了讓這個(gè)操作寫起來省點(diǎn)事(要寫兩遍同樣一個(gè)變量),可以寫成:x += 1
>>> x = 9
>>> x += 1
>>> x
10
除了數(shù)字,字符串進(jìn)行增量賦值,在實(shí)際中也很有價(jià)值。
>>> m = "py"
>>> m += "th"
>>> m
'pyth'
>>> m += "on"
>>> m
'python'
更多建議: