Python入門筆記5 - 條件、循環和其他語句

  • 參考書《Python基礎教程(第三版)》—— Magnus Lie Hetland

一、再看print和import

1. print()函數

  1. 原型print( para,para,..,(sep = para),(end = para) ):none
  2. print()可以打印一個表達式,這個表達式要麼是字符串,要麼自動轉爲字符串形式打印
  3. print()中可以填任意多個參數,關鍵字實參sepend可以缺省
    1. sep指定打印的兩個參數間的間隔符缺省爲空格' '
    2. end指定打印的字符串的後綴缺省爲換行符'\n'
#缺省sep和end
>>> print('A',1,2) 
A 1 2

#設置sep爲'_'
>>> print('A',1,2,sep = '_') 
A_1_2

#設置sep和end
>>> print('A',1,2,sep = '_',end = '*')
A_1_2*

#end尾綴可以是字符串
>>> print('A',1,2,sep = '_',end = 'AAAA')
A_1_2AAAA

2. import

  1. 從模塊導入

    1. 導入一個模塊:import 模塊名
      • 調用方法/函數:模塊名.方法/函數名(),這裏是方法/函數的引用
      • 訪問屬性:模塊名.屬性名,這裏是原屬性的引用
    2. 導入一個模塊中的所有屬性和方法/函數:from 模塊名 import *
      • 調用方法/函數:方法/函數名(),這裏是方法/函數的引用
      • 訪問屬性:屬性名,這裏是原屬性的拷貝
    3. 導入某個方法:from 模塊名 import 方法名
    4. 導入某幾個方法:from 模塊名 import 方法名1,方法名2,方法名3
  2. 如果有兩個模塊包含一樣的方法名(如open)

    1. 給模塊起別名:improt 模塊名 as 別名
    2. 給方法起別名:from 模塊名 import 方法名 as 別名

二、特殊賦值方法

1. 序列解包

  1. 序列解包:將一個序列或任何可迭代對象解包,並將得到的值存儲到一系列變量中
>>> values = 1,2,3
>>> values
(1, 2, 3)

#對元組進行解包
>>> x,y,z = values
>>> x,y,z
(1, 2, 3)
>>> x
1
>>> x,y
(1,2)

#利用序列解包交換變量值
>>> x,y = y,x 
>>> x,y,z
(2, 1, 3)
  1. 序列解包在使用返回元組(或其他數列、可迭代對象啊)的函數/方法時很有用
>>> items = {'name': 'Tom', 'age': 18}
>>> key,value = items.popitem()	#字典的popitem()方法,任意彈出字典中一個鍵值對
>>> key
'age'
>>> value
18
  1. 收集參數
    1. 使用序列解包時,要確保左邊給出的目標數目和被解包序列元素個數相同,否則出錯
    2. “帶*變量” 收集多餘的序列元素,這樣帶*變量得到一個列表
    3. 這種方法可以用到函數參數列表中
>>> A,B = [1,2,3,4]	#報錯

>>> A,B,*rest = [1,2,3,4]
>>> rest
>>> [3,4]

>>> A,B,*rest = [1,2,3]
>>> rest
>>> [3]

>>> A,*rest,B = [1,2,3,4,5]
>>> rest
>>> [2,3,4]

2. 鏈式賦值

x = y = somefunction()	
#等價於	
y = somefunction()
x = y

3. 增強賦值

  • 可以使用+=-=,類似C++
>>> a = 10
>>> a += 2
>>> a
12

>>> str = 'ABC'
>>> str += 'D'
>>> str
'ABCD'

三、條件和條件語句 if-elif-else

1. 布爾值

  1. 標準真值是True/False,它們是1和0的別名
>>> True+1
2
>>> False == 0
True
  1. 用作布爾表達式時

    1. 以下被解釋爲False:False / None / 0 / '' / () / [] / {}
    2. 其他被解釋爲True
  2. bool和list一樣,可以用來轉換其他值構造bool類型

>>> bool("ABC")
>>> True

>>> bool('')
False

2. 條件語句

  • if-elif-else結構
if expression1:
	# code
elif expression2:
	# code
...
elif expressionN:
	# code
else:
	# code

3. 布爾表達式

  1. 比較運算符
符號 說明
傳統比較運算符 == / != / > / < / >= / <= 類似C/C++中的比較符號
鏈式比較 1 <= number <= 10 等價於1 <= number && number <= 10
對象比較 is / is not 比較兩個對象是否爲同一個對象;而==比較兩個對象是否相等 (不可將is用於比較數和字符串等不可改變的基本值,鑑於python在內部處理這些對象的方式,這樣做的結果是不可預測的)
成員資格檢查 in / not in x in y檢查x是否爲容器y的成員
# '=='檢查兩個對象是否相等
# 'is'檢查兩個對象是否相同(“指向同一個對象” / 或者時說“是同一個對象”)
>>> x = y = [1,2,3] # 等價於y = [1,2,3], x = y
>>> z = [1,2,3]

>>> x == y	
True
>>> x == z
True
>>> x is y
True
>>> x is z
False
  1. 字符串和序列的比較
    1. 字符串是根據字符的字母排序進行比較的

    2. 本質上比較的是unicode編碼,字符是按碼點排列的

      • 可以用ord(char)返回字符的Unicode值
      • 可以用chr(int)將Unicode值轉爲字符返回
    3. 序列的比較方式也是這樣的

>>> ord('A') 
65		
>>> chr(65)
'A'

>>> [1,2]<[2,1]
True
>>> [2,[1,4]]<[2,[1,5]]
True
  1. 邏輯運算符

    1. 邏輯運算符用來連接多個布爾表達式,構成複合條件表達式
    2. python中的邏輯運算符:and / or / not
    3. python的符合條件語句也有短路特性
    運算符 操作 說明
    and 與運算 類似C中&&
    or 或運算 類似C中||
    not 非運算 類似C中!

4. 斷言

  1. 斷言是if的“親戚”,僞代碼類似如下:
# 斷言的僞代碼
if not condition:
	crash program
  1. 斷言的目的在於在程序出錯時立刻崩潰,而不是錯誤隱藏到之後再崩潰

  2. 基本上,可以用斷言要求某些條件得到滿足,比如判斷參數合法

  3. 斷言的形式assert 條件表達式 (,'報錯字符串')

# 條件滿足,斷言報錯不被觸發
>>> age = 10
>>> assert 0 < age < 100	

# 條件不滿足,觸發斷言報錯
>>> age = -1
>>> assert 0 < age < 100	
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError

#可以在assert斷言後加一個說明字符串,這樣報錯的時候可以看到說明
>>> age = -1
>>> assert 0 < age < 100, "Age Error"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: Age Error

四、循環語句

1. while循環

while 判斷條件:
	循環體

2. for循環

  1. 基本上,可迭代對象是可以用for循環遍歷的對象。(後面再介紹迭代器,目前把可迭代對象視爲序列即可)
# 遍歷列表打印
words = ['apple','big','car']
for word in words:
	print(word)	

numbers = [1,2,3,4,5,6,7,8,9,10]
for num in numbers:
	print(num)
  1. 爲了方便遍歷特定範圍的數據,python提供內置函數range(begin,end)
>>> range(0,10)
range(0,10)
>>> list(range(0,10))
[0,1,2,3,4,5,6,7,8,9]
			
>>> list(range(5))
[0,1,2,3,4,5]
  1. 還可以加上步進長度參數range(begin,end,step)
>>> list(range(10,0,-1))
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]

>>> list(range(10,0,-2))
[10, 8, 6, 4, 2]

>>> list(range(10,0,-3))
[10, 7, 4, 1]
  1. 可以用類似序列的方法用for循環遍歷字典,但是字典內部是沒有順序的,所有這樣for循環打印的順序是不一定的,只能保證所有值都被處理。如果順序很重要,可以把鍵或值存入一個列表,對列表進行排序,再迭代
#打印所有鍵值對
d = {'x':1,'y':2 }
for key in d:
    print(key,":",d[key])

#打印所有鍵值對(使用了序列解包)
d = {'x':1,'y':2 }
for key,value in d.items():
    print(key,":",value)

3. 迭代工具

  • python提供了一系列可以幫助迭代的函數,其中一些位於itertools模塊中,另外還有一些內置函數

(1)並行迭代 zip()

  • 有時候可能想並行迭代兩個序列,可以用zip(a,b,c...)任意多個序列"縫合"起來,並返回一個由元組組成序列可以把它轉換爲列表查看
  • 當被縫合的序列長度不同時,zip將只縫合併返回最短序列長度個元素
>>> list1 = [1,2,3]
>>> list2 = ['A','B','C']
>>> list3 = [4,5,6,7,8,9]
>>> list(zip(list1,list2,list3))
[(1, 'A', 4), (2, 'B', 5), (3, 'C', 6)]

  • zip配合序列解包,可以方便地進行多序列並行迭代
#不使用zip
names = ['Tom','Bill','Jack']
ages = [12,20,18]
for i in range(len(names)):
	print(names[i],'is',ages[i],'years old')

#使用zip
names = ['Tom','Bill','Jack']
ages = [12,20,18]
for name,age in zip(names,ages):
	print(name,'is',age,'years old')

(2)迭代時獲取索引

  • 利用enumerate(可迭代對象)函數:返回一個由元組組成序列每個元組是由索引和元素值組成,用list()可以把這個序列轉爲元組列表。
>>> list(enumerate(['A','B','C','D'])) 
[(0, 'A'), (1, 'B'), (2, 'C'), (3, 'D')]

>>> list(enumerate('string'))          
[(0, 's'), (1, 't'), (2, 'r'), (3, 'i'), (4, 'n'), (5, 'g')]

# 一個示例 ------------------------
lst = ['BBC','CCTV','ABC']
for index,item in enumerate(lst):
	if 'B' in item:
		lst[index] = 'X'

print(lst)	# 打印['X', 'CCTV', 'X']

(3)反向迭代和排序後再迭代

  • python提供了兩個內置函數reversed(可迭代對象):list_reverseiterator objectsorted(可迭代對象):list,它們不修改原對象,而是返回反轉後的“列表反向迭代對象”和“排序後的列表”
lst = [4,3,5,7,6,5]
print(list(reversed(lst)))	#打印[5, 6, 7, 5, 3, 4]
print(sorted(lst))	        #打印[3, 4, 5, 5, 6, 7]
  • 注意:sorted()返回一個列表reversed()返回一個類似zip的更神祕的可迭代對象,我們不必關心這個到底意味着什麼,在for循環或join等方法中使用完全沒問題。但是不能對它進行索引或切片操作,也不能對它調用列表方法。要想當作列表一樣用的話,可以用list()對返回對象進行轉換

4. 跳出循環

  • break(跳出循環)
#打印1~49
i = 1
while i<100:
	if i == 50:#打印到50時跳出
		break
	print(i)
	i += 1
  • continue(跳過本次循環)
#打印1 2 4 5
i = 1
while i <= 5:
    if i == 3:	#i==3時跳過
        i += 1
        continue
    print(i)
    i += 1

五、簡單推導和字典推導

  • 推到不是語句,而是表達式
  • 列表推導是一種從其他列表創建列表的方法,類似集合推導,工作原理類似for循環
# 基本形式
>>> [x*x for x in range(10)]
[0,1,4,9,16,25,36,49,64,81,100]

# 增加一條if
>>>[x*x for x in range(10) if x % 3 == 0]
[0,9,36,81]

# 增加for
>>>[(x,y) for x in range(3) for y in range(4)]
[(0, 0), (0, 1), (0, 2), (0, 3), (1, 0), (1, 1), (1, 2), (1, 3), (2, 0), (2, 1), (2, 2), (2, 3)]

# 也可同時加入更多的if和for
>>>[x*x for x in range(10) if x % 3 == 0 and x*x<10]
[0,9]

>>>[x*x for x in range(10) if x % 3 == 0 if x*x<10]#可以連寫if代替複合條件
[0,9]
  • 將上面的[]換成()不能實現元組推導,這樣做將創建生成器

  • 可以用{}進行字典推導

>>> squares = {i:"{} squared is {}".format(i,i**2) for i in range(10)}
>>> squares[8]
'8 squared is 64'

六、其他語句del/pass/exec/eval

1. pass語句

  • pass語句不做任何事
  • pass可以用作佔位符,因爲python中的代碼塊不能爲空,用pass填充代碼塊,可以讓程序運行並測試已經寫好的部分
flag = input()
if flag == '1':
	print("...")
elif flag == '2':	#分支沒有寫好,先跳過
	pass		
else:
	print("xxx")
  • 也可以插入一個字符串用作佔位符,這種做法尤其適合未完成的函數和類,因爲這種字符串將充當文檔字符串
def fibs(num):
	'lalalala'	# 文檔字符串(這個字符串會被作爲函數的一部分儲存起來)
	result = [0,1]
	for i in range(num-2):
		result.append(result[-2]+result[-1])
	return result

print(fibs.__doc__)		# 打印lalalala

2. exec語句

  • exec將字符串作爲代碼執行
>>> exec("print('Hello,world')")
Hello,world
  • 大多數情況下,還應該向它傳遞一個命名空間——用於存放變量的地方,否則將污染命名空間同名時覆蓋原本代碼中的變量或函數
>>> from math import sqrt
>>> scope = {}				# 定義一個字典作爲命名空間
>>> exec('sqrt = 1',scope)	# exec的第二個參數指出命名空間,否則這裏的sqrt會污染從math導入的import
>>> sqrt(4)					# 導入的sqrt正常運行
2.0
>>> scope['sqrt']			# 指定命名空間scope,通過exec執行賦值語句創建的變量位於scope中
1
  • exec是一個過程,無返回值
  • 注意exec可能引入不安全的代碼

3. eval語句

  • eval計算用字符串表示的Python表達式值,並返回結果
# 創建一個python計算器
>>> eval(input("Enter an arithmetic expression:"))
  • 類似exec,也可以像eval提供命名空間

4. del語句

  • python中帶有垃圾回收機制,如果一個對象沒有任何人引用,將會被自動回收
>>> d = dict([('name','Tom') , ('age',18)]) 
>>> d = None	#這時剛剛創建的字典將被釋放空間
  • del語句也可以做到這一點,它不僅刪除變量到對象的引用關係,還刪除變量名稱。但是del語句不會刪除對象(事實上,python中無法手動釋放對象,python的垃圾回收機制會自動釋放不用的對象)
>>> x = [1,2,3]
>>> y = x
>>> del x
>>> y	# 刪除x後,對象沒有消失,y仍然可引用;但若y也刪除,列表對象被自動回收
[1,2,3]
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章