例子
#for x in [1,2,3]: #列表 # print(x) #for x in (1,2,3): #元組 # print(x)
文件本身也是個可迭代的對象:
創建一個new file:data.txt在里面寫入
優品課堂
學編程 好心情
www.codeclassroom.com
www.youpinketang.com
www.uke.cc
再在main.py里寫入
f = open('data.txt',encoding='utf8') for line in f: #for line在剛才的f里 print(line, end=' ') #遍歷出來結果的行,結尾用空格結束
1、迭代協議:_next_()
_next_()不是暴露出來給客戶調用,可以獲取下一個元素,就是一行一行讀 next:所占內存空間不變的情況,如果想獲得數據,移到下一項,移動指針用的
pyhon console里寫入
f = open('data.txt',encoding='utf8')
f.__next__()
'優品課堂\n'
典型支持迭代協議對象
>>> f = open('data.txt',encoding='utf8') >>> next(f) '優品課堂\n' >>> next(f) '學編程 好心情\n' >>> next(f) 'www.codeclassroom.com\n'
>>>f = open ('data.txt',encoding='utf8') >>> for x in f.readlines(): #返回一個列表,把所有行找到放到list里,不寫ReadLines好,數據大不支持還是用for...open更好不占太多內存 ... print(x) ... 優品課堂 學編程 好心情 www.codeclassroom.com www.youpinketang.com www.uke.cc
調用全局函數直接寫next
列表:可迭代的對象
>>> urls = ['youpinketang.com','uke.cc','codeclassroom.com'] >>> for url in urls: ... print(url) ... youpinketang.com uke.cc codeclassroom.com
2、迭代工具for...推導...map...
(1)迭代對象
(2)可迭代對象
f = open('data.txt',encoding='utf8') f.__next__() '優品課堂\n' for i in [1,2,3]: print(i) 1 2 3 f = open('data.txt',encoding='utf8') for line in f: print(line) 優品課堂 學編程 好心情 www.codeclassroom.com www.youpinketang.com www.uke.cc
結果一樣差別在於f本身具備next方法,但是列表沒有
iter(f) is f#iter全局函數包起來f判斷一下f是不是應用了迭代器功能,返回true證明使用next方法 True
>>> f = open('data.txt',encoding='utf8') >>> iter(f) is f #iter全局函數包起來f判斷一下f是不是應用了迭代器功能,返回true證明使用next方法 True True >>> f.__next__() '優品課堂\n' >>> next(f)#把f傳進去本質同上 '學編程 好心情\n'
列表:不具有上面的功能,套一個進去就可以用了
>>> iter(urls) is urls #判斷列表是否本身有迭代器,發現不是 False >>> i = iter(urls)#所以沒有next,用for實現,或迭代器等於urls把剛才的傳進去 >>> i.__next__() 'youpinketang.com'
>>> next(i)
'uke.cc'
手動迭代,返回一個列表中所有元素,要平方值
法1使用for 次啰嗦
>>> l = [1,2,3] >>> res = [] #做個空列表 >>> for x in l: ... res.append(x**2) #裝列表的最加x平方項 ... >>> res [1, 4, 9]
法2手動實現不用for 最啰嗦
>>> i = iter(l) #iter全局的方法把列表加進去 >>> while True: ... try: ... ... x = res.append(next(i) ** 2) # i里取個值放入res里,追加 ... ... except StopIteration: # 捕獲異常跳出循環 ... ... break >>> res [1, 4, 9, 1, 4, 9]
法3實際開發,手推導 推薦使用
result = [x**2 for x in l] result [1, 4, 9]
字典表
用for找元素
>>> emp = {'name':'Tom','age':20,'job':'dev','salary':8000.00} >>> for k,v in emp.items(): ... ... print(k,v) ... name Tom age 20 job dev salary 8000.0 >>> emp.items()#看items類型,發現不是列表雖然很像 dict_items([('name', 'Tom'), ('age', 20), ('job', 'dev'), ('salary', 8000.0)]) >>> for k in emp: ... ... print(k) ... name age job salary >>> emp.keys()#看所有鍵 dict_keys(['name', 'age', 'job', 'salary']) >>> emp.values()#也不是列表 dict_values(['Tom', 20, 'dev', 8000.0])
不用for找挨個元素
>>> keys = emp.keys()#先聲明一個keys,看類型 >>> keys dict_keys(['name', 'age', 'job', 'salary']) >>> iter(keys) is keys#看是keys本身嗎false不包含next方法 False >>> i = iter(keys) >>> i.__next__() 'name' >>> i.__next__() 'age' >>> i.__next__() 'job' >>> i.__next__() 'salary'
可迭代都可放入推導表達式內,推導的基礎:前半截是返回的結果,中間是過濾的過程,后面if是過濾的條件:res4 = [url for url in urls if url.endswith('.com')]#過濾,地址包含.com
>>> l = [1,2,3,4,5] >>> res1 = [x for x in l]#在l遍歷,每個元素放穩定變量x,取x本身放入x,[]表示返回列表 >>> type(res1) <class 'list'> >>> res1 [1, 2, 3, 4, 5] >>> res2 = [x+10 for x in l] #列表找單個數把數字每個加10 >>> res2 [11, 12, 13, 14, 15] >>> urls = ['youpinketang.com','uke.cc','codeclassroom.com'] >>> res3 = [url.upper() for url in urls]#變大寫 >>> res3 ['YOUPINKETANG.COM', 'UKE.CC', 'CODECLASSROOM.COM'] >>> res4 = [url for url in urls if url.endswith('.com')]#過濾,地址包含.com >>> res4 ['youpinketang.com', 'codeclassroom.com']
法2 繁瑣
>>> res5 = [] >>> for x in urls: ... ... if x.endswith('.com'): ... ... res5.append(x) ... >>> res5 ['youpinketang.com', 'codeclassroom.com']
3、內置可迭代對象 range()生成序列,它不是列表雖然和列表很像
>>> range(50) range(0, 50) >>> r = range(1,20)#1-20序列 >>> type(r) <class 'range'> >>> for x in range(1,11): ... print(x) ... 1 2 3 4 5 6 7 8 9 10 >>> result = [x**2 for x in range(1,6)]#1-5平方值算出 >>> result [1, 4, 9, 16, 25]
可迭代對象 :1自己實現next方法 2 沒有
range用法:
測試
>>> r = range(1,6) >>> iter(r) is r #r生成的迭代器是它本身嗎 False
不允許
>>> r = range(1,6) >>> iter(r) is r False >>> i = iter(r) #r自動生成next方法 >>> i.__next__() 1 >>> next(i)#也可用全局的方法 2
zip用法:將連個集合合成一個,本質也是可迭代對象
>>> result = zip(['x','y','z'],[1,2,3]) #xyz調用123 >>> result <zip object at 0x000000000358C188> >>> for x in result:#遍歷 ... ... print(x) #結果變成元組 ... ('x', 1) ('y', 2) ('z', 3)
map用法:main.py 把一個數字乘以2
def double_number(x): return x * 2 l = [1,2,3,4,5] result = list(map(double_number,l) ) #把l列表的每一個元素都應用函數double nmber,map是挨個傳播 print(result)
函數:
1目的:最大化代碼重用dry不用重復自己
最小化代碼冗余
過程分解
2定義:def函數名(參數1,...):函數體
如計算兩數相乘
def multiply(x, y): return x * y
3調用:函數名(實際參數)
def multiply(x, y): return x * y print(multiply(3.14,5))
試試字符串能否相乘,發現可以:字符串的特性
print(multiply('優品課堂',5))
模擬看書過程:封裝執行語句形成命令
def read_book():#重復利用()表面執行操作 print('拿到一本書')#邏輯 print('看書') print('收起') read_book()#調用函數
#接收參數傳遞信息 def learning(): print('報名') print('學習') print('退出') learning()
細化信息:通過參數形式列舉
#接收參數傳遞信息 def learning(name, course, start, end):#需要給相應的參數,形式參數 print('{}報名課程:《{}》'.format(name,course))#格式化字符串 print('從第{}節學習到第{}節.format(start, end)') print('{}學習結束.format(name)') learning('Tom','Python入門',1,3)#實際應用,實際參數
可以從外面向里面傳遞信息,也可以從里面向外面傳遞信息
#learning('Tom','Python入門',1,3)#實際應用 def add_number(x,y): #計算兩個數據和,add添加數字 result = x + y #先聲明一個result return result #返回一個值給調用者 #print(add_number(5,3)) a = 10 result = a + add_number(5,3) print(result)
假定兩個序列找重復序列
def intersect(seq1, seq2): #兩個序列以為是列表 res = []#放入空列表 for x in seq1: #找第一個序列元素放x里,聲明參數是在本地定義一個變量 if x in seq2: #如果第二個也有也放進去 res.append(x) #放入空列表里 return res s1 = 'uke.cc' s2 = 'youpinketang.com' l = intersect(s1, s2)#放入一個新結果 print(l)#打印看有哪些
換
s1 = 'abcdefg'
實際開發方便用推導
4變量作用域
(1)Global全局:global
(2)local本地
x = 55 def func():#定義函數,函數里定義的作用的范圍是它里面的屬於本地的(local) x = 99 #賦值99 print(x) print('全局x:',x) print('函數內x:')#函數內x為多少 func()# func是執行邏輯
全局55 內99
如果想用全局的加個global
x = 55 def func():#定義函數 global x x = 99 #x為外部的 print(x) print('全局x:',x) print('函數內x:')#函數內x為多少 func()# func是執行邏輯 print('全局x:',x)
第一次:函數沒執行是55,第二次x是外部的了,把x給改了打印的是99,第三次x已經改變所以為99
(3)built-in:作用最范圍廣
(4)enclousure封裝 :nonlocal
函數套函數:邏輯是先定義再調用
def func():#定義函數 x = 100#第二次打印的是外側x,外層x稱之為封裝 def nested():#嵌套 x = 99 print(x) nested()#調用,第一次執行的是它 print(x) func()#func執行,自帶print
答案:99 100
有時候也想用外側的,可寫聲明nonlocal 非本地的
def func():#定義函數 x = 100#第二次打印的是外側x,外層x稱之為封裝 def nested():#嵌套 nonlocal x #非本地的 x = 99 print(x) nested()#調用,第一次執行的是它 print(x) func()#func執行,自帶print
答案:99 99
5參數
改變數字
def change_numer(x):#默認情況下參數定義沒有寫類型 x += 10 x = 5 #傳x為5整型不可改變 print('x={}'.format(x))#第一次打印x change_numer(x) #執行改變操作 print('x={}'.format(x))#第二次再打x
答案:5 5
改變列表
def change_list(l): l[0] = 99#傳遞過來的列表第一個元素標記為99 l = ['uke.cc','codeclassroom.com','youpinketang.com'] print('原始列表:',l) change_list(l) print('操作后列表:',l)
答案:
原始列表: ['uke.cc', 'codeclassroom.com', 'youpinketang.com']
操作后列表: [99, 'codeclassroom.com', 'youpinketang.com']
改變字符串
def change_str(s): s = 'uke.cc' url = 'youpinketang.com' print(url) change_str(url) print(url)
答案:
youpinketang.com
youpinketang.com
規律:參數 傳遞 不可變類型,傳遞副本給函數,函數內操作不影響原始值(int,float,str,tuple)
可變類型,傳遞地址引用,函數內操作可能會影響原始值(列表,字典表)
不變類型直接操作值,而列表只是個引用,改變了會影響它的值。