Python 是一種相當高級的語言,通過 Python 解釋器把符合語法的程序代碼轉(zhuǎn)換成 CPU 能夠執(zhí)行的機器碼,然后執(zhí)行。Python 非常簡潔,完成同一個任務(wù),C 語言要寫? 1000 行代碼,Java 只需要寫 100 行,而 Python 可能只要 20 行,但是 Python 的運行速度稍慢。
安裝 python 后可以通過文本編輯器來保存代碼 .py,通過命令行模式來運行代碼,而 Python 自帶的 IDLE(交互模式)可以用來驗證代碼。也可以直接用 IDE 集成開發(fā)環(huán)境來編寫和運行代碼。
第一部分 Python基礎(chǔ)
數(shù)據(jù)類型和變量、輸入輸出、字符串和編碼、list tuple dict set 、條件判斷、循環(huán)、函數(shù)、切片 迭代 列表生成器 生成器 迭代器
1. Python 用 # 來注釋,用縮進表示語法。Python 區(qū)分大小寫。
縮進按照約定俗成的習慣,堅持使用 4 個空格的縮進(把 tab 設(shè)置為 4 個空格)。
優(yōu)點:強迫寫出縮進較小的代碼,把一段很長的代碼拆分成若干函數(shù)。
缺點:“復(fù)制-粘貼”功能失效,需要在 IDLE 上重新檢查縮進。
1. 數(shù)據(jù)類型、常變量、四種運算
2. 字符串和編碼
3. 輸入和輸出
3.1 輸出
print('hello,world')
print('100+300=',100+300)
print('hello ,','world')
print('hello,'+'world')
# 結(jié)果:hello,world
print('bang ! '*3)
# 結(jié)果:bang ! bang ! bang !
print(type(2))
# 結(jié)果:
復(fù)制代碼
search = '168'
num_a = '138-6168-0006'
num_b = '168-1222-0006'
print(search + ' is at ' + str(num_a.find(search)) + ' to ' + str(num_a.find(search)+len(search)) + ' of num_a ')
print(search + ' is at ' + str(num_b.find(search)) + ' to ' + str(num_b.find(search)+len(search)) + ' of num_b ')
# 結(jié)果:
168 is at 5 to 8 of num_a
168 is at 0 to 3 of num_b
復(fù)制代碼
2. 輸出多個字符串用逗號 "," 隔開,print() 依次打印每個字符串,遇到逗號 ","會輸出一個空格。
3. 在 print() 函數(shù)中,"+" 在整數(shù)和浮點數(shù)中為運算符,在字符型中為連接符。字符串與整數(shù)、浮點數(shù)一起輸出必須用 ",",不能用 "+" 。
3.2 輸入
name=input('please enter your name')
print('hello,',name)
4. 在 input() 函數(shù)中添加字符串可以提示用戶輸入內(nèi)容。
3.3 格式化
3.3.1 用 % 格式化
5. %d 整數(shù) %f 浮點數(shù) %s 字符串 %x 十六進制整數(shù)。
print( 'Hello, %s' % 'world')
print('Hi, %s, you have $%d.') % ('Michael', 1000000)
print('%2d-%02d' % (3, 1)) ?# 結(jié)果:3-01
print( '%.2f' % 3.1415926) ? ?# 結(jié)果:3.14
6. 有幾個 %? 占位符,后面就跟幾個變量或者值,順序要對應(yīng)好。如果只有一個 %?,括號可以省略。
7. 格式化整數(shù)和浮點數(shù)可以指定是否補 0 和整數(shù)與小數(shù)的位數(shù)。
8. 如果不太確定應(yīng)該用什么,%s 永遠起作用,它會把任何數(shù)據(jù)類型轉(zhuǎn)換為字符串。
9. 字符串里面的 % 是一個普通字符,用 %% 來表示一個 % 。
3.3.2 用 format 格式化
print('Hello, {}'.format('world'))
print('Hi, {}, you have ${}.'.format ('Michael', 1000000))
4. list 和 tuple
4.1 列表 list []
10. list 是一種有序的集合,可以隨時添加和刪除其中的元素。
classmates = ['Michael', 'Bob', 'Tracy']
print(classmates) # 結(jié)果:['Michael', 'Bob', 'Tracy']
11. 用 len() 函數(shù)可以獲得 list 元素的個數(shù)。
print(len(classmates)) # 結(jié)果:3
12. 順序索引、逆序索引。
print(classmates[0],classmates[1],classmates[2]) # 結(jié)果:Michael Bob Tracy
print(classmates[-1], classmates[-2],classmates[-3]) # 結(jié)果:Tracy Bob Michael
13. 在 list 末尾添加元素、在 list 指定位置添加元素、添加多個元素。
classmates.append('Adam')
print(classmates) # 結(jié)果:['Michael', 'Bob', 'Tracy', 'Adam']
classmates.insert(1, 'Jack')
print(classmates) # 結(jié)果:['Michael', 'Jack', 'Bob', 'Tracy']
classmates = ['Michael', 'Bob', 'Tracy']
classmates.extend(['Adam', 'Jack'])
print(classmates)
# 結(jié)果:['Michael', 'Bob', 'Tracy', 'Adam', 'Jack']
14. 刪除 list 末尾的元素、刪除指定位置的元素。
classmates.pop()
print(classmates) # 結(jié)果:['Michael', 'Bob']
classmates.pop(1)
print(classmates) # 結(jié)果:['Michael', 'Tracy']
classmates = ['Michael', 'Bob', 'Tracy']
classmates.remove('Bob') ? ?# 用 remove 刪除要指定元素
print(classmates)
classmates = ['Michael', 'Bob', 'Tracy']
del classmates[2]
print(classmates)
15. 更新某個元素。
classmates[1] = 'Sarah'
print(classmates) # 結(jié)果:['Michael', 'Sarah', 'Tracy']
16. list 中可以包含各種數(shù)據(jù)類型。
L = ['Apple', 123, True]
17. 嵌套 list。
s = ['python', 'java', ['asp', 'php'], 'scheme']
print(len(s)) ? ?# 結(jié)果:4
print(s[2][0]) # 結(jié)果:asp
4.2 元組 tuple ()
18. tuple 初始化后不能修改,其它同 list ( len()、索引、可以是任何數(shù)據(jù)類型、嵌套)。
classmates = ('Michael', 'Bob', 'Tracy')
19. 只有1個元素的 tuple 定義時必須加一個逗號 “,” ,來消除歧義(數(shù)學計算意義上的括號)。
t = (1,)
print(t) # 結(jié)果:(1,)
20. "可變的"tuple (嵌套) 。
t = ('a', 'b', ['A', 'B'])
t[2][0] = 'X'
t[2][1] = 'Y'
print(t) # 結(jié)果:('a', 'b', ['X', 'Y'])
21. tuple 所謂的"不變"是說 tuple 的每個元素指向永遠不變,即指向 'a' ,不能改成指向 'b' ,指向一個 list ,不能改成指向其他對象,但指向的這個 list 本身是可變的。要創(chuàng)建一個內(nèi)容也不變的 tuple ,就必須保證 tuple 的每一個元素本身也不能變。
5. dict 和 set
5.1 字典 dic {}
22. 內(nèi)置的字典,全稱dictionary,在其他語言中稱為map,使用鍵-值(key-value)存儲,具有極快的查找速度。
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
print(d['Michael']) # 結(jié)果:95
23. 用 len() 函數(shù)可以獲得 dict 元素的個數(shù)。
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
print(len(d)) # 結(jié)果:3
24. 添加 key-value 、添加多個 key-value。
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d['Adam']=67
print(d) # 結(jié)果:{'Adam': 67, 'Bob': 75, 'Tracy': 85, 'Michael': 95}
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d.update({'Adam':67,'Jack':99})
print(d)
25. 更新 value 。
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d['Bob'] = 90
print(d['Bob']) # 結(jié)果:90
26. 刪除 key-value 。dict 沒有 remove
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
d.pop('Bob')
print(d) # 結(jié)果:{'Michael': 95, 'Tracy': 85}
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
del d['Bob']
print(d)
27. 檢查 key 是否在 dict 中。
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
print('Thomas' in d) # 結(jié)果:False
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
print('Michael' in d) # 結(jié)果:True
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
print(d.get('Thomas')) # 結(jié)果:None
d = {'Michael': 95, 'Bob': 75, 'Tracy': 85}
print(d.get('Michael')) # 結(jié)果:95
28. dict 查找和插入快,占用空間大,dict 無序;list 查找和插入慢,占用空間小,list 有序;
dict 的 key 必須是不可變對象 (字符串、整數(shù)等都是不可變的,list 是可變的)。
5.2 set
29. set 和 dict 類似,也是一組 key 的集合,但不存儲 value。由于 key 不能重復(fù),所以,在 set 中,沒有重復(fù)的 key 。
30. set 自動過濾重復(fù)的元素, set 中的元素是無序的。
s = set([2,1,2,3])
print(s) # 結(jié)果:{1, 2, 3}
# {1, 2, 3} 只是告訴你這個 set 內(nèi)部有 1,2,3 這 3 個元素,顯示的順序并不表示 set 是有序的
31. 添加元素。
s = set([2,1,2,3])
s.add(4)
print(s) # 結(jié)果:{1, 2, 3, 4}
32. 刪除元素。set 沒有 del pop 。
s = set([2,1,2,3,4])
s.remove(4)
print(s) # 結(jié)果:{1, 2, 3}
s = {1,2,3,4}
s.discard(4)
print(s)
33. 檢查 key 是否在 set 中。
s = set(['Adam', 'Lisa', 'Bart', 'Paul'])
print('adam' in s) ? ?# 結(jié)果:False
print('Adam' in s) # 結(jié)果:True
34. set 可以看成數(shù)學意義上的無序和無重復(fù)元素的集合,因此,兩個set可以做數(shù)學意義上的并、交、差操作。
s1 = set([1, 2, 3])
s2 = set([2, 3, 4])
s3 = set([1, 2, 3, 4, 5])
print(s1 & s2) ? # 交 ? ? ?結(jié)果:{2, 3}
print(s1 | s2) ? # 并 ? ? ?結(jié)果:{1, 2, 3, 4}
print(s3 - s1) ? # 差 ? ? ?結(jié)果:{4, 5}
35. set 和 dict 的唯一區(qū)別僅在于沒有存儲對應(yīng)的 value ,但是,set 的原理和 dict 一樣。set 不可以放入可變對象,因為無法判斷兩個可變對象是否相等,也就無法保證set 內(nèi)部 “不會有重復(fù)元素”。
5.3 再議不可變對象
a = [6,74,2,3,5,36,5]
a.sort(reverse=True)
print(a)
# 結(jié)果:[74, 36, 6, 5, 5, 3, 2]
a = ['a', 'd', 'c']
a.sort()
print(a) # 結(jié)果:['a', 'c', 'd']
a = 'abc'
a.replace('a','A')
print(a) # 結(jié)果:abc
a = 'abc'
b = a.replace('a','A')
print(a) ? ?# 結(jié)果:abc
print(b) ? ?# 結(jié)果:Abc
當我們調(diào)用 a.replace('a','A') 時,實際上調(diào)用方法 replace 是作用在字符串對象 'abc' 上的,而這個方法雖然名字叫 repalce,但卻沒有改變字符串 'abc' 的內(nèi)容。相反,replace 方法創(chuàng)建了一個新字符串 'Abc' 并返回。如果我們用變量 b 指向該新字符串,則變量 a 仍指向原有的字符串 'abc',但變量 b 卻指向新字符串 'Abc' 了。
6. 條件判斷
比較運算符?? ?==, !=,>, <, <=, >=
成員運算符?? ?in,not in
身份運算符?? ?is,is not
布爾元素符?? ?not,and, or
36.不同類型的對象不能使用 >, <, <=, >= 進行比較,但可以使用 ==, != 比較。浮點數(shù)和整數(shù)可以比較大小。布爾類型可以比較大小,F(xiàn)alse 為 0,True 為 1。
復(fù)制代碼
a = 'a'
b = 'a'
print(a is b)
print(a is not b)
# 結(jié)果:
True
False
復(fù)制代碼
復(fù)制代碼
age = 20
if age >= 6:
print('teenager')
elif age >= 18:
print('adult')
else:
print('kid')
復(fù)制代碼
36. 如果 if 語句判斷是 True ,就執(zhí)行縮進的語句。注意 if、else、elif 后面的 ":" 。
37. if 語句從上往下判斷,如果在某個判斷上是 True ,把該判斷對應(yīng)的語句執(zhí)行后,就忽略掉剩下的 elif 和 else。
38. if 判斷條件可以簡寫,非零數(shù)值、非空字符串、非空 list tuple dict set 等,都判斷為 True,否則為 False 。
x = 8
if x:
print('True')
39. input() 返回的數(shù)據(jù)類型是 str ,str不能直接和整數(shù)比較,要把 str 用 int() 轉(zhuǎn)為整數(shù)。
s = input('birth: ')
birth = int(s)
if birth < 2000:
print('00前')
else:
print('00后')
當 if 后面的布爾表達式過長或者難于理解,可以采取給變量賦值的辦法來儲存布爾表達式返回的布爾值 True 或 False 。
復(fù)制代碼
password_list = ['*#*#', '12345']
def account_login():
password = input('Password')
password_correct = password == password_list[-1]
password_reset = password == password_list[0]
if password_correct :
print('Login success!')
elif password_reset :
new_password = input('Enter a new password:')
password_list.append(new_password)
print('Your password has changed successfully')
account_login()
else:
print('Wrong password or invalid input!')
account_login()
account_login()
復(fù)制代碼
7. 循環(huán)
7.1 for...in 循環(huán),遍歷 list、tuple、disc、set
40. for x in y 循環(huán)就是把 y 中每個元素代入變量 x ,然后執(zhí)行縮進塊的語句。
names = ['Michael', 'Bob', 'Tracy']
for name in names:
print(name)
復(fù)制代碼
# 對list中的每一個元素,如果在set中,就將其刪除,如果不在set中,就添加進去
s = set(['Adam', 'Lisa', 'Paul'])
L = ['Adam', 'Lisa', 'Bart', 'Paul']
for a in L:
if a in s :
s.remove(a)
else:
s.add(a)
print(s)
復(fù)制代碼
# 遍歷如下的dict,打印 name: score
d = {'Adam': 95,'Lisa': 85,'Bart': 59}
for key in d :
print(key+':',d[key])
# 遍歷如下的set,打印出 name: score
s = set([('Adam', 95), ('Lisa', 85), ('Bart', 59)])
for x in s:
print(x[0] + ':', x[1])
41. range() 函數(shù)生成整數(shù)序列,list() 函數(shù)把整數(shù)序列轉(zhuǎn)換為 list。 [ set()、tuple() 同 ]
例如 range(5) 生成從0開始小于5的整數(shù)序列。
print(list(range(5))) # 結(jié)果:[0, 1, 2, 3, 4]
print(set(range(5))) ?# 結(jié)果:{0, 1, 2, 3, 4}
sum = 0
for x in [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]:
sum = sum + x
print(sum)
sum = 0
for x in range(101):
sum = sum + x
print(sum)
7.2 while 循環(huán),條件滿足時進行循環(huán),條件不滿足時退出循環(huán)
復(fù)制代碼
# 計算100以內(nèi)所有奇數(shù)之和
sum = 0
n = 99
while n > 0:
sum = sum + n
n = n - 2
print(sum)
復(fù)制代碼
7.3 break 提前退出循環(huán)
復(fù)制代碼
n = 1
while n <= 100:
if n > 10: # 當n = 11時,條件滿足,執(zhí)行break語句
break # break語句會結(jié)束當前循環(huán)
print(n)
n = n + 1
print('END')
復(fù)制代碼
7.4 continue 跳過當前循環(huán),進入下一循環(huán)
n = 0
while n < 10:
n = n + 1
if n % 2 == 0: # 如果n是偶數(shù),執(zhí)行continue語句
continue # continue語句會直接繼續(xù)下一輪循環(huán),后續(xù)的print()語句不會執(zhí)行
print(n)
42.不要濫用 break 和 continue 語句。break 和 continue 會造成代碼執(zhí)行邏輯分叉過多,容易出錯。大多數(shù)循環(huán)并不需要用到 break 和 continue 語句,上面的兩個例子,都可以通過改寫循環(huán)條件或者修改循環(huán)邏輯,去掉 break 和 continue 語句。
7.5 嵌套循環(huán)
for x in ['A', 'B', 'C']:
for y in ['1', '2', '3']:
print(x + y)
復(fù)制代碼
# 打印出100以內(nèi)所有十位數(shù)數(shù)字比個位數(shù)數(shù)字小的數(shù)
a = set(range(10))
a.remove(0)
for x in a:
for y in a:
if x < y:
print(x*10+y)
else:
continue
復(fù)制代碼
8. 函數(shù)
8.1 調(diào)用函數(shù)
Python內(nèi)置了很多有用的函數(shù),我們可以直接調(diào)用。
abs()?? ?返回一個數(shù)的絕對值
max()?? ?返回多個數(shù)中最大的數(shù)
cmp(x, y)?? ?如果 xy,返回 1
int()?? ?把其他數(shù)據(jù)類型轉(zhuǎn)換為整數(shù)
float()?? ?把其它數(shù)據(jù)類型轉(zhuǎn)換為浮點數(shù)
str()?? ?把其它數(shù)據(jù)類型轉(zhuǎn)換為字符串
bool()?? ?把其它數(shù)據(jù)類型轉(zhuǎn)換為布爾值
hex()?? ?把一個整數(shù)轉(zhuǎn)換成十六進制表示的字符串
list()、set()、tuple()?? ?把某序列轉(zhuǎn)換為 list、set、tuple
對函數(shù)使用別名
a = abs # 變量a指向abs函數(shù)
print(a(-1)) # 所以也可以通過a調(diào)用abs函數(shù)
8.2 定義函數(shù)
43. 定義一個函數(shù)要使用 def 語句,依次寫出函數(shù)名、括號、括號中的參數(shù)和冒號":",然后,在縮進塊中編寫函數(shù)體,函數(shù)的返回值用 return 語句返回。如果沒有 return 語句時,自動 return None 。
def my_abs(x):
if x >= 0:
return x
else:
return -x
44.在 Python 交互環(huán)境中定義函數(shù)時,注意 Python 會出現(xiàn) ...的提示。函數(shù)定義結(jié)束后需要按兩次回車重新回到 >>> 提示符下。
45. 定義一個空函數(shù),再沒有想好函數(shù)代碼時讓整個代碼能運行起來。
def nop():
pass
# pass 也可以在其它語句
if age >= 18:
pass
46. 調(diào)用函數(shù)時,Python 解釋器會檢查內(nèi)置函數(shù)的參數(shù)個數(shù)和參數(shù)類型是否正確,而對自定義的函數(shù)只檢查參數(shù)個數(shù),所以我們要在函數(shù)定義中對參數(shù)類型進行檢查。數(shù)據(jù)類型檢查可以用內(nèi)置函數(shù) isinstance() 實現(xiàn)。
復(fù)制代碼
def my_abs(x):
if not isinstance(x, (int, float)):
raise TypeError('bad operand type')
if x >= 0:
return x
else:
return -x
復(fù)制代碼
47. Python 的函數(shù)返回多值其實就是返回一個 tuple 。在語法上,返回一個 tuple 可以省略括號,而多個變量可以同時接收一個 tuple ,按位置賦給對應(yīng)的值。
復(fù)制代碼
# 給出一點的坐標,給出移動位移、角度,計算出新坐標
import math ? ?#導(dǎo)入 math 包
def move(x, y, step, angle=0):
nx = x + step * math.cos(angle)
ny = y + step * math.sin(angle)
return nx, ny
x, y = move(100, 100, 60, math.pi / 6)
print(x, y) ? ? ? ? # 結(jié)果:151.96152422706632 130.0
r = move(100, 100, 60, math.pi / 6)
print(r) ? ? ? ? ? ?# 結(jié)果:(151.96152422706632, 130.0)
復(fù)制代碼
8.3 函數(shù)的參數(shù)
8.3.1 位置參數(shù)
# 計算一個數(shù)的平方
def power(x):
return x * x
復(fù)制代碼
# 計算一個數(shù)的n次方
def power(x, n):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
復(fù)制代碼
48. 位置參數(shù),調(diào)用函數(shù)時,傳入的兩個值按照位置順序依次賦給參數(shù) x 和 n 。
8.3.2 默認參數(shù)
復(fù)制代碼
# 在不傳入n時,n默認為2
def power(x, n=2):
s = 1
while n > 0:
n = n - 1
s = s * x
return s
print(power(5)) ? ?# 結(jié)果:25
print(power(5,3)) ? ?# 結(jié)果:125
復(fù)制代碼
49.設(shè)置默認參數(shù)時,有幾點要注意:可以加下QQ群:533807627
一是必選參數(shù)在前,默認參數(shù)在后,否則Python的解釋器會報錯;
二是當函數(shù)有多個參數(shù)時,把變化大的參數(shù)放前面,變化小的參數(shù)放后面。變化小的參數(shù)就可以作為默認參數(shù)。
50. 默認參數(shù)降低調(diào)用的難度。一旦需要更復(fù)雜的調(diào)用時,又可以傳遞更多的參數(shù)來實現(xiàn)。無論是簡單調(diào)用還是復(fù)雜調(diào)用,函數(shù)只需要定義一個。
51. 有多個默認參數(shù)時,調(diào)用的時候,既可以按順序提供默認參數(shù),也可以不按順序提供部分默認參數(shù)。當不按順序提供部分默認參數(shù)時,需要把參數(shù)名寫上。
def enroll(name, gender, age=6, city='Beijing'):
print('name:', name,' ? ?gender:', gender,' ? ?age:', age,' ? ?city:', city)
enroll('Sarah','F') # 結(jié)果:name: Sarah ? ? gender: F ? ? age: 6 ? ? city: Beijing
enroll('Bob','M',7) # 結(jié)果:name: Bob ? ? gender: M ? ? age: 7 ? ? city: Beijing
enroll('Adam','M',city='Changsha') # 結(jié)果:name: Adam ? ? gender: M ? ? age: 6 ? ? city: Changsha
52. 默認參數(shù)必須指向不變對象。因為不變對象一旦創(chuàng)建,對象內(nèi)部的數(shù)據(jù)就不能修改,這樣就減少了由于修改數(shù)據(jù)導(dǎo)致的錯誤。
復(fù)制代碼
def add_end(L=[]): # 默認參數(shù)為list,為可變對象
L.append('END')
return L
# 正常調(diào)用
print(add_end([1, 2, 3])) ? ? ? # 結(jié)果:[1, 2, 3, 'END']
print(add_end(['x', 'y', 'z'])) # 結(jié)果:['x', 'y', 'z', 'END']
# 默認調(diào)用
print(add_end()) # 結(jié)果:['END']
print(add_end()) # 結(jié)果:['END', 'END']
print(add_end()) # 結(jié)果:['END', 'END', 'END']
# 因為默認參數(shù)L也是一個變量,它指向?qū)ο骩],每次調(diào)用該函數(shù),如果改變了L的內(nèi)容,則下次調(diào)用時,默認參數(shù)的內(nèi)容就變了,不再是函數(shù)定義時的[]了
復(fù)制代碼
8.3.3 可變參數(shù)
53. 可變參數(shù)就是傳入的參數(shù)個數(shù)是可變的,可以是 0 個或任意個參數(shù),這些可變參數(shù)在函數(shù)調(diào)用時自動組裝為一個 tuple 。
復(fù)制代碼
def calc(*numbers): # 參數(shù)前面加了一個*號。在函數(shù)內(nèi)部,參數(shù)numbers接收到的是一個tuple
sum = 0
for n in numbers :
sum = sum + n*n
return sum
print(calc(1,2))
print(calc())
nums = [1, 2, 3]
print(calc(nums[0], nums[1], nums[2]))
print(calc(*nums)) ?# *nums表示把nums這個list的所有元素作為可變參數(shù)傳進去
復(fù)制代碼
8.3.4 關(guān)鍵字參數(shù)
54. 關(guān)鍵字參數(shù)允許你傳入 0 個或任意個含參數(shù)名的參數(shù),這些關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動組裝為一個 dict 。
55. 在調(diào)用該函數(shù)時,可以只傳入必選參數(shù)。也可以傳入任意個數(shù)的關(guān)鍵字參數(shù)。
復(fù)制代碼
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('Michael', 30) ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 結(jié)果:name: Michael age: 30 other: {}
person('Bob', 35, city='Beijing') ? ? ? ? ? ? ? ?# 結(jié)果:name: Bob age: 35 other: {'city': 'Beijing'}
person('Adam', 45, gender='M', job='Engineer') ? # 結(jié)果:name: Adam age: 45 other: {'job': 'Engineer', 'gender': 'M'}
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, city=extra['city'], job=extra['job']) ? # 結(jié)果:name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 結(jié)果:name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
# **extra表示把extra這個dict的所有key-value用關(guān)鍵字參數(shù)傳入到函數(shù)的**kw參數(shù),kw將獲得一個dict,注意kw獲得的dict是extra的一份拷貝,對kw的改動不會影響到函數(shù)外的extra
復(fù)制代碼
56. 默認參數(shù)是所有的調(diào)用函數(shù)都有定義的所有參數(shù)(個數(shù)不變),只是默認參數(shù)的值是默認的;而關(guān)鍵字參數(shù)在調(diào)用函數(shù)時用戶可以傳入任意個數(shù)關(guān)鍵字參數(shù)(個數(shù)可變),只是需要含參數(shù)名,而且定義關(guān)鍵字參數(shù)在函數(shù)內(nèi)部自動組裝為一個 dict 。
8.3.5 命名關(guān)鍵字參數(shù)
對于關(guān)鍵字參數(shù),函數(shù)的調(diào)用者可以傳入任意不受限制的關(guān)鍵字參數(shù)。至于到底傳入了哪些,就需要在函數(shù)內(nèi)部通過 kw 檢查。以 person() 函數(shù)為例,我們希望檢查是否有 city 和 job 參數(shù),但是調(diào)用者仍可以傳入不受限制的關(guān)鍵字參數(shù)??梢约酉翾Q群:533807627
復(fù)制代碼
def person(name, age, **kw):
if 'city' in kw:
# 有city參數(shù)
pass
if 'job' in kw:
# 有job參數(shù)
pass
print('name:', name, 'age:', age, 'other:', kw)
person('Jack', 24, city='Beijing', addr='Chaoyang', zipcode=123456)
復(fù)制代碼
57. 命名關(guān)鍵字參數(shù),只接受指定名字的關(guān)鍵字參數(shù)。命名關(guān)鍵字參數(shù)必須傳入?yún)?shù)名。如果沒有傳入?yún)?shù)名,調(diào)用將報錯(看作位置參數(shù))。
58. 命名關(guān)鍵字參數(shù)需要一個特殊分隔符 *,* 后面的參數(shù)被視為命名關(guān)鍵字參數(shù),如果缺少 *,Python 解釋器將無法識別位置參數(shù)和命名關(guān)鍵字參數(shù)。如果函數(shù)定義中已經(jīng)有了一個可變參數(shù),后面跟著的命名關(guān)鍵字參數(shù)就不再需要一個特殊分隔符 * 。
59. 命名關(guān)鍵字參數(shù)可以有缺省值,從而簡化調(diào)用。
def person(name, age, *, city, job):
print(name, age, city, job)
person('Jack', 24, city='Beijing', job='Engineer') ? ?# 結(jié)果:Jack 24 Beijing Engineer
def person(name, age, *args, city, job):
print(name, age, args, city, job)
person('Jack', 24, city='Beijing', job='Engineer') ? ?# 結(jié)果:Jack 24 () Beijing Engineer
person('Jack', 24, 1, 2, 3, city='Beijing', job='Engineer') ? ?# 結(jié)果:Jack 24 (1, 2, 3) Beijing Engineer
def person(name, age, *, city='Beijing', job):
print(name, age, city, job)
person('Jack', 24, job='Engineer') ? ? ? ?# 結(jié)果:Jack 24 Beijing Engineer
60. 關(guān)鍵字參數(shù),調(diào)用者可以傳或不傳關(guān)鍵字參數(shù),關(guān)鍵字參數(shù)將在函數(shù)內(nèi)部組成 dict ;命名關(guān)鍵字參數(shù)調(diào)用者必須傳入所有的參數(shù)(定義缺省值的除外),而且需要傳入?yún)?shù)名,但是不組成 dict 。命名關(guān)鍵字參數(shù)只是限制參數(shù)的名字;
8.3.6 參數(shù)組合
61. 在 Python 中定義函數(shù),可以用必選參數(shù)、默認參數(shù)、可變參數(shù)、關(guān)鍵字參數(shù)和命名關(guān)鍵字參數(shù)這 5 種參數(shù)組合使用。但參數(shù)定義的順序必須是:參數(shù)定義的順序必須是:必選參數(shù)、默認參數(shù)、可變參數(shù)、命名關(guān)鍵字參數(shù)和關(guān)鍵字參數(shù)。
復(fù)制代碼
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
f1(1, 2) ? ? ? ? ? ? ? ? ? ? ? ?# 結(jié)果:a = 1 b = 2 c = 0 args = () kw = {}
f1(1, 2, 3) ? ? ? ? ? ? ? ? ? ? # 結(jié)果:a = 1 b = 2 c = 3 args = () kw = {}
f1(1, 2, 3, 'a', 'b') ? ? ? ? ? # 結(jié)果:a = 1 b = 2 c = 3 args = ('a', 'b') kw = {}
f1(1, 2, 3, 'a', 'b', x=99) ? ? # 結(jié)果:a = 1 b = 2 c = 3 args = ('a', 'b') kw = {'x': 99}
args = (1, 2, 3, 4)
kw = {'d': 99, 'x': '#'}
f1(*args, **kw) ? ? ? ? ? ? ? ? # 結(jié)果:a = 1 b = 2 c = 3 args = (4,) kw = {'x': '#', 'd': 99}
# *args相當于傳入tuple中的數(shù)字
復(fù)制代碼
復(fù)制代碼
def f2(a, b, c=0, *, d, **kw):
print('a =', a, 'b =', b, 'c =', c, 'd =', d, 'kw =', kw)
f2(1, 2, d=99, ext=None) ? ?# 結(jié)果:a = 1 b = 2 c = 0 d = 99 kw = {'ext': None}
args = (1, 2, 3)
kw = {'d': 88, 'x': '#'}
f2(*args, **kw) ? ? ? ? ? ? # 結(jié)果:a = 1 b = 2 c = 3 d = 88 kw = {'x': '#'}
# 若把 kw 中的第一個 key d 改為其它會報錯,因為沒有傳入命名關(guān)鍵字參數(shù)
復(fù)制代碼
8.4遞歸函數(shù)
一個函數(shù)在內(nèi)部調(diào)用自身本身,這個函數(shù)就是遞歸函數(shù)。典型的例子就是計算階乘。
# n! = 1 x 2 x 3 x ... x n
# (n-1)! = 1 x 2 x 3 x ... x (n-1)
# n! = (n-1)! x n
def fact(n):
if n==1:
return 1
return n * fact(n - 1)
復(fù)制代碼
# fact(5)計算過程
===> 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
復(fù)制代碼
漢諾塔的移動可以用遞歸函數(shù)非常簡單地實現(xiàn)。
復(fù)制代碼
def move(n, a, b, c): ? #將n個盤從a柱移到到c
if n ==1:
print(a, '-->', c) ?#a柱為一個盤時,將僅有的一塊盤a柱移動到c柱
return
else:
move(n-1, a, c, b) ?#a柱盤多于一個時,將n-1個盤從a柱移動到b柱
print(a, '-->', c) ?#當a柱剩一個盤時,將這個盤移動到c柱
move(n-1, b, a, c) ?#將n-1盤從b柱移動到c
move(4, 'a', 'b', 'c')
復(fù)制代碼
9. 高級特性
9.1 切片 slice ?取 list 、tuple、str 的部分元素
復(fù)制代碼
L = ['Michael', 'Sarah', 'Tracy', 'Bob', 'Jack']
print(L[0:3]) ? ? # L[0:3]表示,從索引0開始取,直到索引3為止,但不包括索引3
print(L[:3]) ? ? ?# 如果第一個索引是0,可以省略
print(L[1:3]) ? ? #從索引1開始,取出2個元素出來
# 結(jié)果:['Michael', 'Sarah', 'Tracy']
# 結(jié)果:['Michael', 'Sarah', 'Tracy']
# 結(jié)果:['Sarah', 'Tracy']
print(L[-3:]) ? ? ?# 從索引-3開始開始取,一直到結(jié)束
print(L[-3:-1]) ? ?# 從索引-3開始取,直到索引-1,但不包括-1
# 結(jié)果:['Tracy', 'Bob', 'Jack']
# 結(jié)果:['Tracy', 'Bob']
print(L[0:5:2]) ? ?# 從索引0到索引4,每2個取一個
# 結(jié)果:['Michael', 'Tracy', 'Jack']
復(fù)制代碼
對 list( range() ) 取部分元素。
復(fù)制代碼
L = list(range(100))
print(L)
print(L[:10]) ? # 取前十個元素
print(L[-10:]) ? ?# 取后十個元素
print(L[11:21]) # 取11-20個元素
print(L[:20:2]) ? ?# 取前20個元素,每2個取一個
print(L[::5]) ? #取所有元素,每5個取一個
print(L[:]) ? ? # 取所有元素
復(fù)制代碼
對 tuple、str 取部分元素。
print((0, 1, 2, 3, 4)[:3])
print('ABCDEFG'[:3])
print('ABCDEFG'[::2])
phone_number = '138-6666-0006'
hiding_number = phone_number.replace(phone_number[:9],'*'*9)
print(hiding_number)
# 結(jié)果:*********0006
set 、dict 不可 slice。
9.2 迭代 ?遍歷可迭代對象
復(fù)制代碼
# 迭代 list tuple
L=[1, 2, 3, 4]
for a in L:
print(a)
T=(1, 2, 3, 4)
for b in T
print(b)
復(fù)制代碼
復(fù)制代碼
# 迭代 dict 的 key
d = {'a': 1, 'b': 2, 'c': 3}
for key in d:
print(key)
# 結(jié)果:
b
a
c
# 迭代 dict 的 value
d = {'a': 1, 'b': 2, 'c': 3}
for value in d.values():
print(value)
# 結(jié)果:
2
3
1
# 迭代 dict 中的 key 與 value
d = {'a': 1, 'b': 2, 'c': 3}
for k, v in d.items():
print('k:',v)
# 結(jié)果:
b: 2
c: 3
a: 1
復(fù)制代碼
復(fù)制代碼
# 迭代字符串
for ch in 'ABC':
print(ch)
# 結(jié)果:
A
B
C
復(fù)制代碼
62. 當我們使用 for 循環(huán)時,只要作用于一個可迭代對象,for 循環(huán)就可以正常運行,而不太關(guān)心該對象究竟是 list 還是其他數(shù)據(jù)類型??梢酝ㄟ^ collections 模塊的 Iterable 進行類型判斷。
復(fù)制代碼
from collections import Iterable
print(isinstance('abc', Iterable)) ? ? ? ? ?# str是否可迭代
print(isinstance([1,2,3], Iterable)) ? ? # list是否可迭
print(isinstance({1, 2, 3},Iterable)) ? ?# set是否可迭代
print(isinstance({'a':2 ,'b':2},Iterable)) ? ?# dict是否可迭代
print(isinstance(123, Iterable)) ? ? ? ? ?# 整數(shù)是否可迭代
# 結(jié)果:True
# 結(jié)果:True
# 結(jié)果:True
# 結(jié)果:True
# 結(jié)果:False
復(fù)制代碼
63. 如果要知道迭代的下標,可以使用內(nèi)置的 enumerate 函數(shù)。
for i, value in enumerate(['A', 'B', 'C']):
print(i, value)
# 結(jié)果:
0 A
1 B
2 C
64. for 循環(huán)同時引用兩個變量。
for x, y in [(1, 1), (2, 4), (3, 9)]:
print(x, y)
# 結(jié)果:
1 1
2 4
3 9
for x,y in zip( ['A', 'B', 'C'],['1', '2', '3']):
print(x + y)
# 結(jié)果:
A1
B2
C3
9.3 ?列表生成式
print([x * x for x in range(1, 11)]) ? ?# 生成 [1x1, 2x2, 3x3, ..., 10x10]
print([x * x for x in range(1, 11) if x % 2 == 0]) ? ?# 篩選出僅偶數(shù)的平方
# 結(jié)果:[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
# 結(jié)果:[4, 16, 36, 64, 100]
print([m + n for m in 'ABC' for n in 'XYZ']) ? ?# 兩層循環(huán),生成全排列
# 結(jié)果:['AX', 'AY', 'AZ', 'BX', 'BY', 'BZ', 'CX', 'CY', 'CZ']
d = {'x': 'A', 'y': 'B', 'z': 'C' }
print([k + '=' + v for k, v in d.items()]) ? ?# for循環(huán)同時使用兩個變量
# 結(jié)果:['y=B', 'x=A', 'z=C']
復(fù)制代碼
# 通過一個復(fù)雜的列表生成式把 dict 變成一個 HTML 表格
d = { 'Adam': 95, 'Lisa': 85, 'Bart': 59 }
%s%s
print( '' )
NameScore
print( '\n'.join(tds) )
print( '' )
# 字符串的join()方法可以把一個 list 拼接成一個字符串
# 結(jié)果:
NameScore
Bart59
Lisa85
Adam95
# 把打印出來的結(jié)果保存為一個html文件,就可以在瀏覽器中看到效果
復(fù)制代碼
# lower() 函數(shù)的參數(shù)類型只能是 str ,用列表生成器修改列表 L1 ,保證lower() 正確調(diào)用
L1 = ['Hello', 'World', 18, 'Apple', None]
L2 = [x.lower() for x in L1 if isinstance (x, str)]
print(L2)
# 結(jié)果:['hello', 'world', 'apple']
9.4 生成器 generator可以加下QQ群:533807627
列表容量有限,而且占用很大的存儲空間。通過生成器,列表元素可以按照某種算法推算出來,可以在循環(huán)的過程中不斷推算出后續(xù)的元素。
9.4.1 把列表生成式改成 generator
L = [x * x for x in range(10)] ? ?# 列表生成器
g = (x * x for x in range(10)) ? ?# 生成器 把[]改成()
print(g)
# 結(jié)果: at 0x1022ef630>
打印出 generator 的每個元素有兩種方法:一種是通過 next() 獲得;二是通過 for 循環(huán) (一般用此方法)。
復(fù)制代碼
# 通過 next() 打印出 generator 的每個元素
g = (x * x for x in range(3))
print(next(g))
print(next(g))
print(next(g))
print(next(g)) # 沒有更多的元素時,拋出StopIteration的錯誤
# 結(jié)果:
0
1
4
Tracebacke (most recent call last):
File xxxxx,line x , in xx
StopIteration
復(fù)制代碼
復(fù)制代碼
# 通過 for 循環(huán)來迭代
g = (x * x for x in range(3))
for n in g: # 不會產(chǎn)生 StopIteration 的錯誤
print(n)
# 結(jié)果:
0
1
4
復(fù)制代碼
9.4.2 通過函數(shù)實現(xiàn)復(fù)雜邏輯的 generator
如果推算的算法比較復(fù)雜,用類似列表生成式的 for 循環(huán)無法實現(xiàn)的時候,還可以用函數(shù)來實現(xiàn)。
65. generator 的函數(shù),在每次調(diào)用 next() 的時候執(zhí)行,遇到 yield 語句返回,再次執(zhí)行時從上次返回的 yield 語句處繼續(xù)執(zhí)行。
復(fù)制代碼
# 用函數(shù)生成斐波拉契數(shù)列(除第一個和第二個數(shù)外,任意一個數(shù)都可由前兩個數(shù)相加得到)1, 1, 2, 3, 5, 8, 13, 21, 34, ...
def fib(max):
n, a, b = 0, 0, 1
while n < max:
yield b ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?# 把函數(shù)中的 return 改為 yield,函數(shù)就變成 generator
a, b = b, a + b
n = n + 1
return 'done'
f = fib(6)
print(f)
# 結(jié)果 :
for n in f:
print(n)
# 結(jié)果 :
1
1
2
3
5
8
復(fù)制代碼
a, b = b, a + b 的解釋
復(fù)制代碼
# 用函數(shù)生成楊輝三角
def triangles():
L = [1]
while True:
yield L
L.append(0)
L = [L[i-1] + L[i] for i in range(len(L))]
n = 0
for t in triangles():
print(t)
n = n + 1
if n == 10:
break ? ? ? # 如果沒有 break ,將無限循環(huán)
# 結(jié)果:
[1]
[1, 1]
[1, 2, 1]
[1, 3, 3, 1]
[1, 4, 6, 4, 1]
[1, 5, 10, 10, 5, 1]
[1, 6, 15, 20, 15, 6, 1]
[1, 7, 21, 35, 35, 21, 7, 1]
[1, 8, 28, 56, 70, 56, 28, 8, 1]
[1, 9, 36, 84, 126, 126, 84, 36, 9, 1]
復(fù)制代碼
楊輝三角的算法解釋(來源:半分幻的兇鳥)
9.5 迭代器 Iterator
可以用 for 循環(huán)的對象統(tǒng)稱為可迭代對象 Iterable 。包括:list tuple dict set str / generator [isinstance(xxx,Iterable)]
可以被 next() 函數(shù)調(diào)用并不斷返回下一個值的對象稱為迭代器 Iterator 。生成器都是 Iterator 對象 [isinstance(xxx,Iterator)]
Python 的 Iterator 對象表示的是一個數(shù)據(jù)流,Iterator 對象可以被 next() 函數(shù)調(diào)用并不斷返回下一個數(shù)據(jù),直到?jīng)]有數(shù)據(jù)時拋出 StopIteration 錯誤??梢园堰@個數(shù)據(jù)流看做是一個有序序列,但我們卻不能提前知道序列的長度,只能不斷通過 next() 函數(shù)實現(xiàn)按需計算下一個數(shù)據(jù),所以 Iterator 的計算是惰性的,只有在需要返回下一個數(shù)據(jù)時它才會計算。Iterator 甚至可以表示一個無限大的數(shù)據(jù)流,例如全體自然數(shù)。而使用 list 是永遠不可能存儲全體自然數(shù)的??梢约酉翾Q群:533807627
使用 iter() 函數(shù)可以把 list tuple dict set str 等 Iterable 變成 Iterator。
復(fù)制代碼
from collections import Iterator
print(isinstance([], Iterator)) ? ? # 結(jié)果:False
print(isinstance({}, Iterator)) ? ? # 結(jié)果:False
print(isinstance('', Iterator)) ? ? # 結(jié)果:False
print(isinstance(iter([]), Iterator)) ? ? # 結(jié)果:True
print(isinstance(iter({}), Iterator)) # 結(jié)果:True
print(isinstance(iter(''), Iterator)) ? ? # 結(jié)果:True
復(fù)制代碼
小結(jié):
文中對 list 、tuple、dict、set 的區(qū)別與聯(lián)系寫的不夠清晰,在這里再總結(jié)一下
有/無序?? ?可切片?? ?可迭代?? ?可列表生成?? ?len()?? ?刪除?? ?添加?? ?更改
list?? ?有?? ?可?? ?可[enumerate()]?? ?可?? ?可?? ?.pop(索引)/.remove(元素)/del [索引]?? ?.append(元素)/.insert(索引,元素)/.extend([])?? ?[索引]=
tuple?? ?有?? ?可?? ?可?? ?—?? ?可?? ?—?? ?—?? ?—
dict?? ?無?? ?不可?? ?可[key/.values()/.items()]?? ?—?? ?可?? ?.pop(key)/del [key]?? ?[key]=/.update({})?? ?[key]=
set?? ?無?? ?不可?? ?可?? ?—?? ?可?? ?.remove(元素)/.discard(元素)?? ?.add(元素)
自己如何確定目標
在生活中學會不斷挖掘自己的潛力。我們都是一個普通人,可能并不清楚自己到底在哪方面占有優(yōu)勢。所以,學著在生活中找到自己的優(yōu)勢,并根據(jù)優(yōu)勢選擇一定的就業(yè)方向。
不隨波逐流。不要看周圍的人做什么,自己就做什么,也許別人做的并不適合你。別人的優(yōu)勢很可能會成為你的劣勢。所以,堅定自己的想法,讓自己知道那些方面適合自己,自己可以勝任。
不斷嘗試可能成為自己的優(yōu)勢。你不知道什么適合自己,所以才要大膽、勇敢地嘗試。找到一種可以屬于你的獨特的優(yōu)勢。
堅定信念。一旦你堅定了自己的信念,就不要被別人的意見或是諷刺或是嘲笑所干擾。別人不是你,不懂的你在想什么,不清楚你開始這件事的源頭。你的事情,不了解你的人,沒有資格輕易評說。
不茫然,不多想。別讓太多的事干擾到你奮斗下去的信念。夢想不容許太多的雜念。那些雜念只會讓你的心愈來愈脆弱,多為一個人考慮,到頭來,傷害的還是自己。
選擇自己學習方法
每個人都有適合自己的方法,有的人去選擇自學,有的人選擇看視頻學習,有的人選擇報名培訓班,那在這個時候,你就要自己考慮清楚,到底那樣對的幫助是最大的,個人覺得是跟著培訓班最好的,畢竟人家的實戰(zhàn)項目多,我們學軟件開發(fā)的都知道實戰(zhàn)項目對于學好一門語言是 很重要的。
學習python有那些誤區(qū)
具體里面的誤區(qū)非常的多,那些就不需要我去寫出來,我給你說的一般都是心態(tài)的問題,首先一個覺得自己會java和c++,然后我學習python就很牛,但是你要知道語言是有很多相同的地方,但是不是通用,一定要自己學習的仔細。還有一種就是覺得我不會英語,我要先去把英語學習好在來學python。因為自己想還壞主意然后學習,這樣的都是容易找進誤區(qū)的。
怎么樣才能學好python
學好python你需要一個良好的環(huán)境,一個優(yōu)質(zhì)的開發(fā)交流群,群里都是那種相互幫助的人才是可以的,我有建立一個python學習交流群,在群里我們相互幫助,相互關(guān)心,相互分享內(nèi)容,這樣出問題幫助你的人就比較多,群號是304加上050最後799,這樣就可以找到大神聚合的群,如果你只愿意別人幫助你,不愿意分享或者幫助別人,那就請不要加了,你把你會的告訴別人這是一種分享。
感覺寫的好,對你有幫助,就點個贊唄,別光只收藏哈.~( ̄▽ ̄)~
?