python基礎教程_學習筆記7:條件、循環、其它語句

條件、循環、其它語句

printimport

隨着更加深入地學習python,可能會出現這種感覺:有些自以爲已經掌握的知識點,還隱藏着一些讓人驚訝的特性。

 

使用逗號輸出

打印多個表達式,只要將這些表達式用逗號隔開即可:

>>> print "age:",28

age: 28

參數之間都插入了一個空格符。

 

如果在結尾加上逗號,那麼接下來的語句會與前一條語句在同一行打印:

print "Hello,",

print "World!"

結果:

Hello, World!

把某件事作爲另一件事導入

從模塊導入函數的時候,可以使用:

import somemodule

from somemodule import somefunction

from sommodule import somefunction,anotherfunction,yetanotherfunction

from somemodule import *

其中,只有確定自己想要從給定的模塊導入所有功能時,才應該使用最後一個版本。

 

如果兩個模塊都有open函數,應該怎麼做呢?

只需使用第一種方式導入,然後像下面這樣使用函數:

module1.open(...)

module2.open(...)

 

但還有另外的選擇:可以在語句末尾增加一個as語句,在該子句後給出名字,或爲整個模塊提供別名

>>> import math as foobar

>>> foobar.sqrt(4)

2.0

也可以爲函數提供別名:

>>> from math import sqrt as foobar

>>> foobar(4)

2.0

對於open函數,可以像下面這樣使用:

from module1 import open as open1

from module2 import open as open2

 

賦值魔法

序列解包

多個賦值操作可以同時進行:

>>> x,y,z=1,23,456

>>> print x,y,z

1 23 456

用它交換兩個(或多個)變量:

>>> x,y=y,x

>>> print x,y

23 1

 

>>> x,y,z=y,z,x

>>> print x,y,z

1 456 23

事實上,這裏所做的事情叫做序列解包或可迭代解包——將多個值的序列解開,然後放到變量的序列中

>>> values=1,2,3

>>> values

(1, 2, 3)

>>> x,y,z=values

>>> print x,y,z

1 2 3

當函數或者方法返回元組(或者其他序列或可迭代對象)時,這個特性尤其有用。假設需要獲取(和刪除)字典中的任意的鍵-值對,可以使用popitem方法,這個方法將鍵值對作爲元組返回,那麼這個元組可以直接賦值到兩個變量中:

>>> people={'name':'signjing','age':'28','weight':'72'}

>>> x,y=people.popitem()

>>> print x,y

age 28

>>> x,y=people.popitem()

>>> print x,y

name signjing

>>> x,y=people.popitem()

>>> print x,y

weight 72

它允許函數返回一個以上的值並且打包成元組,然後通過一個賦值語句很容易進行訪問。所解包的序列中的元素數量必須和放置在賦值符號=左邊的變量數量完全一致,否則python會在賦值時引發異常:

>>> x,y=1,3,4

 

Traceback (most recent call last):

  File "<pyshell#27>", line 1, in <module>

    x,y=1,3,4

ValueError: too many values to unpack

>>> x,y,z=2,9

 

Traceback (most recent call last):

  File "<pyshell#28>", line 1, in <module>

    x,y,z=2,9

ValueError: need more than 2 values to unpack

 

鏈式賦值

鏈式賦值是將同一個值賦給多個變量的捷徑。

x=y=somefunction()

和下面語句的效果是一樣的:

y=somefunction()

x=y

注意:上面的語句和下面的語句不一定等價:

x=somefunction()

y=somefunction()

 

增量賦值

將表達式運算符放置在賦值運算符=的左邊,這種寫法叫做增量賦值,對於*/%等標準運算符都適用:

>>> x=5

>>> x+=3

>>> x*=2

>>> x/=4

>>> x

4

 

對於其他數據類型也適用(只要二元運算符本身適用於這些數據類型即可):

>>> s='too'

>>> s+='many'

>>> s*=2

>>> s

'toomanytoomany'

 

語句塊

語句塊是在條件爲真(條件語句)時執行或執行多次的一組語句。在代碼前放置空行來縮進語句即可創建語句塊。

 

塊中的每行都需要縮進相同的量。

 

很多語言使用特殊單詞或者字符(比如begin{)來表示一個語句塊的開始,用另外的單詞或字符(如end})表示語句塊的結束。

python中,冒號(:)用來標識語句塊的開始,塊中的每一個語句都是縮進的(縮進量相同)。當回退到和已經閉合的塊一樣的縮進量時,就表示當前塊已經結束了。

 

條件和條件語句

布爾變量

下面的值在作爲布爾表達式時候,會被解釋看做假(False):

False None 0 “” () [] {}

換句話說,也就是標準值FalseNone、所有類型的數字0(包括浮點數、長整型和其它類型)、空序列(比如空字符串、元組和列表)以及空的字典都爲假。其它的一切都解釋爲真,包括特殊值True

標準的真值爲TrueFalse。事實上,TrueFalse只不過是10的“華麗”說法而已。

>>> True

True

>>> False

False

>>> True==0

False

>>> True==1

True

>>> False==0

True

>>> False==1

False

>>> False+True+23

24

 

布爾值TrueFalse屬於布爾類型,bool函數可以用來(和liststr以及tuple一樣)轉換其它值。

>>> bool('I think ,therefore I am')

True

>>> bool(42)

True

>>> bool(0)

False

>>> bool('')

False

>>> bool(False)

False

>>> bool(())

False

>>> bool({})

False

>>> bool([])

False

 

因爲所有值都可以用作布爾值,所以幾乎不需要對它們進行顯式轉換(可以說python會自動轉換這些值)。

 

注意:儘管[]””都是假植(也就是說bool([])==bool(“”)==False),它們本身並不相等。對於其他不同類型的假值對象也是如此(例如,()!=False)

 

條件執行和if語句

if語句可以實現條件執行,如果條件判定爲真,則後面的語句塊執行,如果條件爲假,語句塊就不會被執行。

name=raw_input("Please input a name: ")

if name.endswith("Bob"):

        print "Hello,Bob!"

 

如果用戶輸入了以Bob結尾的名字,則打印出問候語。

else語句

else子句(之所以叫子句,是因爲它不是獨立的語句,而只能作爲if語句的一部分)可以增加一種選擇。

 

name=raw_input("Please input a name: ")

if name.endswith("signjing"):

        print "Hello,signjing!"

else:

        print "Hello,someone!"

如果第1個語句塊沒有被執行,則轉入第2個語句塊。

elif語句

如果需要檢查多個條件,就可以使用elif,它是“else if”的簡寫,也是ifelse子句的聯合使用——也就是具有條件的else子句。

 

num=input("Please input a num: ")

if num>0:

        print "num > 0"

elif num<0:

        print "num < 0"

else:

        print "num = 0"

嵌套代碼塊

if語句裏可以嵌套使用if語句:

num = input("Please input a num: ")

if num > 0:

        if num >5:

                print "num > 5"

        elif num > 3:

                print "num >3 and num <= 5"

        else:

                print "num <= 3 and num > 0"

elif num < 0:

        if num < -10:

                print "num < -10"

        elif num < -4:

                print "num < -4 and num >= -10"

        else:

                print "num >= -4 and num < 0"

else:

        print "num = 0"

更復雜的條件

比較運算符

表達式 描述

x==y x等於y

x<y x小於y

x>y x大於y

x>=y x大於等於y

x<=y x小於等於y

x!=y x不等於y

x is y xy是同一個對象

x is not y xy是不同的對象

x in y xy容器的成員

x not in y x不是y容器的成員

 

比較不兼容類型

理論上,對於相對大小的任意兩個對象xy都是可以使用比較運算符比較的,並且都會得到一個布爾值結果。但是只有在xy是相同或者近似類型的對象時,比較纔有意義。

 

python中比較運算和賦值運算一樣是可以連接的——幾個運算符可以連在一起使用:

>>> a=5

>>> 0<a<8

True

>>> 0<a<3

False

>>> 0<a>3

True

 

相等運算符

想要知道兩個東西是否相等,應該使用相等運算符,即兩個等號==

>>> "abc"=="abc"

True

>>> "abc"=="Abc"

False

 

單個相等運算符是賦值運算符,是用來改變值的,不能用來比較。

 

is:同一性運算符

這個運算符比較有趣,它看起來和==一樣,但事實上卻不同:

>>> x=y=[1,2,3]

>>> z=[1,2,3]

>>> x==y

True

>>> x is y

True

>>> x == z

True

>>> x is z

False

 

xz相等卻不等同,因爲is運算符是判定同一性而不是相等性。

xy被綁定到同一個列表上,而變量z被綁定在另外一個具有相同數值和順序的列表上。它們的值可能相等,但卻不是一個對象。

 

in:成員資格運算符

之前說明過了,此處略;

 

字符串和序列比較

字符串可以按照字母順序排列進行比較。

>>> "a" < "b"

True

>>> "abc" < "ab"

False

注意:實際的順序可能會因爲使用不同的locale而和上面的例子有所不同

其他的序列也可以以相同的方式進行比較,不過比較的不是字符而是元素的其它類型:

>>> [1,2,4]>[1,2,3]

True

>>> [1,2,[2,'a']]<[1,2,[3,4]]

True

 

布爾運算符

and運算符,連接兩個布爾值,且在兩者都爲真時返回真,否則返回假。

or運算符,連接兩個布爾值,且在兩者都爲假時返回假,否則返回真。

not運算符,連接一個布爾值,當連接的布爾值爲真時返回假,爲假時返回真。

 

短路邏輯

x and y需要兩個變量都爲真時才爲真,如果x爲假,則x and y立即返回false,而不需計算y的值。同理,x or y只要有一個爲真則爲真,如果x爲真,則x or y直接返回True,而不需計算y的值。這樣,避免了無用地執行代碼,可以作爲一種技巧使用。

斷言

if語句有個非常有用的近親,其工作方式多少有點像下面這樣(僞代碼):

if not condition:

crash program

這樣做是因爲與其讓程序在晚些時候崩潰,不如在錯誤條件出現時直接讓它崩潰。一般來說,你可以要求某些條件必須爲真。語句中使用的關鍵字爲assert

>>> age=10

>>> assert 0<age<102

>>> age=-2

>>> assert 0<age<102

 

Traceback (most recent call last):

  File "<pyshell#39>", line 1, in <module>

    assert 0<age<102

AssertionError

 

如果需要確保程序中的某個條件一定爲真才能讓程序正常工作的話,assert語句就有用了,可以在程序中置入檢查點:

條件後可以添加字符串(用逗號把條件和字符串隔開),用來解釋斷言:

>>> assert 0<age<102, 'make age right'

 

Traceback (most recent call last):

  File "<pyshell#42>", line 1, in <module>

    assert 0<age<102, 'make age right'

AssertionError: make age right

循環

while循環

用來在任何條件爲真的情況下重複執行一個代碼塊。

i=5

while i>0:

        print i

        i-=1

結果:

5

4

3

2

1

 

for循環

list1=list('signjing')

for l in list1:

        print l

結果:

s

i

g

n

j

i

n

g

 

numbers=[1,2,3,4]

for n in numbers:

        print n

結果:

1

2

3

4

 

迭代(循環的另一種說法)某個範圍的數字是很常見的,有個內建的函數可供使用:

for n in range(1,5):

        print n

結果:

1

2

3

4

 

range函數的工作方式類似於分片,包含下限,不包含上限,如果希望下限爲0,則可以只提供上限。

 

提示:

如果能使用for循環,就儘量不使用while循環。

循環遍歷字典元素

一個簡單的for語句就能循環字典的所有鍵,就像處理序列一樣:

d={'x':1,'y':2,'z':3}

for key in d:

        print key,d[key]

結果:

y 2

x 1

z 3

 

for循環的一大好處就是可以在循環中使用序列解包:

d={'x':1,'y':2,'z':3}

for key,value in d.items():

        print key,value

結果:

y 2

x 1

z 3

 

一些迭代工具

python中迭代序列(或其它可迭代對象)時,一些函數非常有用。有些函數位於itertools模塊,還有些python的內建函數也十分有用。

並行迭代

程序可以同時迭代兩個序列:

names=['anne','beth','damon']

ages=[13,19,21]

for i in range(len(names)):

        print names[i],'is',ages[i],'years old.'

結果:

anne is 13 years old.

beth is 19 years old.

damon is 21 years old.

 

內建的zip函數可以用來進行並行迭代,把兩個序列“壓縮”在一起,然後返回一個元組的列表:

names=['anne','beth','damon']

ages=[13,19,21]

for name,age in zip(names,ages):

        print name,"is",age,"years old."

結果:

anne is 13 years old.

beth is 19 years old.

damon is 21 years old.

 

zip函數可以作用於任意多的序列。關於它很重要的一點是zip可以應付不等長的序列:當最短的序列“用完”的時候就會停止:

>>> zip(range(5),xrange(100))

[(0, 0), (1, 1), (2, 2), (3, 3), (4, 4)]

>>> zip(range(5),xrange(2))

[(0, 0), (1, 1)]

 

編號迭代

有些時候想要迭代序列中的對象,同時還要獲取當前對象的索引。

暫略;

 

翻轉和排序迭代

reversedsorted,同列表的reversesort方法類似,但作用於任何序列或可迭代對象上,不是原地修改對象,而是返回翻轉或排序後的版本:

>>> sorted([4,3,6,8,3])

[3, 3, 4, 6, 8]

>>> sorted('hello,world!')

['!', ',', 'd', 'e', 'h', 'l', 'l', 'l', 'o', 'o', 'r', 'w']

>>> list(reversed('hello,world!'))

['!', 'd', 'l', 'r', 'o', 'w', ',', 'o', 'l', 'l', 'e', 'h']

>>> ''.join(reversed('hello,world'))

'dlrow,olleh'

跳出循環

break

結束循環可以使用break語句。

for i in range(5):

        print i

        if i > 2:

                break

        print "--"

結果:

0

--

1

--

2

--

3

 

continue

continue語句用的要少很多,它讓當前的迭代結束,“跳”到下一輪循環的開始。基本意思是:跳過剩餘的循環體,但不結束循環。當循環體很大而且很複雜時,會很有用。

for i in range(5):

        print i

        if i > 2:

                continue

        print "--"

結果:

0

--

1

--

2

--

3

4

while True/break習語

while True實現了一個永遠不會自己停止的循環,但在循環體內部的if語句中加入條件,在條件滿足時調用break語句。這樣,就可以在循環內部任何地方而不是隻在開頭終止循環。

 

儘管應該小心在代碼中頻繁使用break語句,但這個特殊的技術用得非常普遍。

循環中的else子句

當在循環體內部使用break語句時,通常是因爲找到了某物或某事發生了,在跳出時做一些事情是簡單的,但有些時候想要在沒有跳出之前做些事情。可以在循環中增加一個else語句——僅在沒有調用break時執行。

for i in range(5):

        print i

        if i > 6:

                break

        print "--"

else:

        print "I'm here"

結果:

0

--

1

--

2

--

3

--

4

--

I'm here

 

forwhile循環中都可以使用continuebreak語句和else子句。

列表推導式——輕量級循環

列表推導式是利用其它列表創建新列表的一種方法。工作方式類似於for循環。

>>> [x*x for x in range(1,6)]

[1, 4, 9, 16, 25]

可以增加判斷條件:

>>> [x*x for x in range(1,6) if x%2==0 ]

[4, 16]

可以增加更多的for語句:

>>> [x*y for x in range(1,3) for y in (2,5)]

[2, 5, 4, 10]

也可以和if語句聯合使用:

>>> [x*y for x in range(1,11) for y in range(1,9) if x%3==0 if y%4==0 ]

[12, 24, 24, 48, 36, 72]

 

注意:for循環部分和if語句部分之間都沒有標點符號。

三人行

什麼都沒發生

有些時候,程序什麼事情都不用做:

>>> pass

>>> 

 

name=raw_input("Please input a name: ")

if name == 'signjing':

        print "I'm signjing"

elif name == 'sj':

        pass

else:

        print "unknown"

執行:

Please input a name: signjing

結果:

I'm signjing

 

執行:

Please input a name: sj

 

如果將pass行註釋:

if name == 'signjing':

        print "I'm signjing"

elif name == 'sj':

        #pass

else:

        print "unknown"

執行報錯:

  File "pass.py", line 6

    else:

       ^

IndentationError: expected an indented block

使用del刪除

一般來說,python解釋器(以其無窮的智慧)自動刪除那些不再使用的對象。另一種方法是使用del語句,它不僅會移除一個對象的引用,也會移除那個名字本身。

>>> x=['hello','world']

>>> y=x

>>> y[1]='python'

>>> x

['hello', 'python']

>>> del x

>>> y

['hello', 'python']

 

事實上,python中是沒有辦法刪除值的,因爲值不再使用時,python解釋器會負責內存的回收。

使用execeval執行和求值字符串

有些時候會動態地創造python代碼,然後將其作爲語句執行或作爲表達式計算,這近似於“黑暗魔法”——在此之前,一定要慎之又慎,仔細考慮:

 

exec

執行一個字符串的語句是exec

>>> exec "print 'hello'"

hello

但使用簡單形式的exec語句絕不是好事。很多時候可以給它提供命名空間——可以放變量的地方。

 

>>> from math import sqrt

>>> exec "sqrt = 1"

>>> sqrt(4)

 

Traceback (most recent call last):

  File "<pyshell#70>", line 1, in <module>

    sqrt(4)

TypeError: 'int' object is not callable

可以通過in <scope>來實現,其中<scope>就是起到放置代碼字符串命名空間作用的字典。

>>> from math import sqrt

>>> scope={}

>>> exec "sqrt = 1" in scope

>>> sqrt(4)

2.0

>>> scope['sqrt']

1

可見,潛在的破壞性代碼並不會覆蓋sqrt函數,原來的函數能正常工作,而通過exec賦值的變量sqrt只在它的作用域內有效。

 

注意,如果需要將scope打印出來的話,能看到其中包括很多東西,因爲內建的__builtins__字典自動包含所有的內建函數和值:

>>> len(scope)

2

>>> scope.keys()

['__builtins__', 'sqrt']

 

eval

eval(用於“求值”)是類似於exec的內建函數。

exec語句會執行一系列的python語句,而eval會計算python表達式,並返回結果值。

exec語句並不返回任何對象,因爲它本身就是語句。

>>> eval(raw_input("Enter an arithmetic expression: "))

Enter an arithmetic expression: 2*6+8

20

發佈了69 篇原創文章 · 獲贊 73 · 訪問量 24萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章