Python全棧(第一期)Day15
今日主要內容:
生成器和迭代器複習
通過python查詢檔案內容
some面試題
python‘s內建函式
一,迭代器和生成器複習
迭代器和生成器 迭代器 可迭代協議 —— 含有iter方法的都是可迭代的 迭代器協議 —— 含有next和iter的都是迭代器 特點 節省記憶體空間 方便逐個取值,一個迭代器只能取一次。 生成器 —— 本質就是迭代器 生成器函式 含有yield關鍵字的函式都是生成器函式 生成器函式的特點 呼叫之後函式內的程式碼不執行,返回生成器 每從生成器中取一個值就會執行一段程式碼,遇見yield就停止。 如何從生成器中取值: for :如果沒有break會一直取直到取完 next :每次只取一個 send :不能用在第一個,取下一個值的時候給上個位置傳一個新的值 資料型別強制轉換 :會一次性把所有資料都讀到記憶體裡 生成器表示式 (條件成立想放在生成器中的值 for i in 可迭代的 if 條件)
二,作業
case1:處理檔案,使用者指定要查詢的檔案和內容,將檔案中包含要查詢內容的每一行都輸出到螢幕。
def check_file(filename, aim): with open(filename, encoding='utf-8') as f: #控制代碼 : handler,檔案操作符,檔案控制代碼 for i in f: if aim in i: yield i g = check_file('1.複習.py', '生成器') for i in g: print(i.strip()) 輸出結果: # 迭代器和生成器 # 生成器 —— 本質就是迭代器 # 生成器函式 # 含有yield關鍵字的函式都是生成器函式 # 生成器函式的特點 # 呼叫之後函式內的程式碼不執行,返回生成器 # 每從生成器中取一個值就會執行一段程式碼,遇見yield就停止。 # 如何從生成器中取值: # 生成器表示式 # (條件成立想放在生成器中的值 for i in 可迭代的 if 條件)
case2:寫生成器,從檔案中讀取內容,在每一次讀取到的內容之前加上‘***’之後再返回給使用者。
def check_file(filename):
with open(filename, encoding='utf-8') as f: #控制代碼 : handler,檔案操作符,檔案控制代碼
for i in f:
yield '***'+i
for i in check_file('1.複習.py'):
print(i.strip())
三,some面試題
第一題:
def demo(): for i in range(4): yield i g = demo() g1 = (i for i in g) g2 = (i for i in g1) print(list(g1)) print(list(g2)) ''' 理解: 1,g1和g2都是生成器,取值的時候都是從頭往後取值。 2,list(g1)--->g1 = (i for i in g)---->找g取值---->demo()' for迴圈執行 3,list(g2)--->g2 = (i for i in g1)--->找g1取值--->找g取值--->但是此時g的值已經取完了! '''
輸出結果:
[0, 1, 2, 3]
[]
第二題:
def add(n, i):
return n+i
def test():
for i in range(4):
yield i
g = test()
'''
一種簡便方法:
對於for迴圈套生成器的問題--->我們可以把程式碼拆開算
'''
for n in [1, 10, 5]:
g = (add(n, i) for i in g)
# n = 1
# g = (add(1, i) for i in test())
# n = 10
# g = (add(n, i) for i in (add(n, i) for i in test()))
# n = 5
# g = (add(n, i) for i in (add(n, i) for i in (add(n, i) for i in test())))
'''
請注意:
到此為止,我上面的程式碼沒有取任何數值,上面的for迴圈都是生成器表示式
生成器表示式只會得到一個生成器,並不會取值。
'''
print(list(g))
輸出結果:
[15, 16, 17, 18]
四,內建函式
1,知識點
內建函式一共:68個
反射相關:4
面向物件相關:9
基礎資料型別相關:38
print()
input()
len()
type()
open()
tuple()
list()
int()
bool()
set()
dir()
id()
str()
迭代器/生成器相關:3 —> range next iter
作用域相關:2 —> locals() globals()
其他:12
2,一些重要的內建函式
'''
區分這四個:
global nonlocal 是關鍵字,宣告變數用的。
'''
print(locals()) #返回本地作用域中的所有名字
print(globals()) #返回全域性作用域中的所有名字
# global 變數
# nonlocal 變數
Note: 我們平時不常用雙下劃綫函式,因為太麻煩。所以我們常用下面兩種呼叫方式。
迭代器.__next__()
next(迭代器)
迭代器 = 可迭代的.__iter__()
迭代器 = iter(可迭代的)
*下一個知識點~~~~*
'''
range:是可迭代的,但是不是迭代器。
iter:
iter(iterable) -> iterator
Get an iterator from an object.
'''
print('__next__' in dir(range(1, 11, 2)))
print('__next__' in dir(iter(range(1, 11, 2))))
輸出結果:
False
True
# callable:
# Return whether the object is callable (i.e., some kind of function).
print('one:', callable(print))
a = 1
print('two:', callable(a))
print('three:', callable(globals))
def func():
pass
print('four:', callable(func))
輸出結果:
one: True
two: False
three: True
four: True
'''
下面兩種方式等效:
都是兩種匯入模組的方式
'''
#case1:
import time
print(time.time())
#case2:
t = __import__('time')
print(t.time())
輸出結果:
1543835381.702548
1543835381.702548
#兩種新方法:
f = open('1.複習.py')
print(f.writable())
print(f.readable())
輸出結果:
False
True
# hash - 對於相同可hash資料的hash值在一次程式的執行過程中總是不變的
# - 字典的定址方式:雜湊值可以理解為key的地址,這個地址可以找到value。
# - 再想一下為什麼字典的key必須是可雜湊的?
print(hash(12345))
print(hash('Hello python'))
print(hash(('1', 'aaa')))
#print(hash([])) #因為列表是不可雜湊,所以這裡程式會報錯
輸出結果:
12345
333291261833905208
3021913203957254173
'''print自帶有換行符--->可以自己看一下print的原始碼
'''
print('我們的祖國是花園', end='') #指定輸出的結束符
print('我們的祖國是花園')
print(1, 2, 3, 4, 5, sep='|') #指定輸出多個值之間的分隔符
#思考一個問題:為什麼print能夠輸出到螢幕上?
#因為螢幕也是相當於一個檔案!
#下面我們這個例子就是直接print到了檔案裡!
f = open('file', 'w')
print('Hello python', file=f)
f.close()
輸出結果:
我們的祖國是花園我們的祖國是花園
1|2|3|4|5
這裡好像少了一點輸出?
# 列印進度條
import time
for i in range(0, 101, 2):
time.sleep(0.1)
char_num = i//2
per_str = '\r%s%% : %s\n' % (i, '*' * char_num) \
if i == 100 else '\r%s%% : %s' % (i, '*'*char_num)
print(per_str, end='', flush=True)
print('Training done')
'''
progress Bar: 是一個模組專門用來列印進度條的!
'''
輸出結果:
100% : **************************************************
Training done
3,一些另類內建函式
eval('print(123)')
exec('print(123)')
print(eval('1+2+3+4')) # 有返回值
print(exec('1+2+3+4')) #沒有返回值
# exec和eval都可以執行 字串型別的程式碼
# eval只能用在你明確知道你要執行的程式碼是什麼
# eval有返回值 —— 有結果的簡單計算
# exec沒有返回值 —— 簡單流程控制
輸出結果:
123
123
10
None
code = '''for i in range(10):
print(i*'0') '''
exec(code)
輸出結果:
0
00
000
0000
00000
000000
0000000
00000000
000000000
'''
compile:將字串型別的程式碼進行編譯,程式碼物件能夠通過exec語句來執行或者eval進行求值
'''
code1 = 'for i in range(0,10): print (i)'
compile1 = compile(code1, '', 'exec') #如果是從檔案中讀取程式碼,'filename'
exec(compile1)
code2 = '1 + 2 + 3 + 4'
compile2 = compile(code2, '', 'eval')
print(eval(compile2))
輸出結果:請注意這裡有兩個輸出喲
0
1
2
3
4
5
6
7
8
9
10
階段總結:
exec:流程類
eval:計算類
single:互動類
'''
exec:流程類
eval:計算類
single:互動類
'''
code3 = 'name = input("please input your name:")'
compile3 = compile(code3, '', 'single')
exec(compile3) #執行時顯示互動命令,提示輸入
print(name)
#執行後name變數有值
輸出結果:
please input your name:nanshan
nanshan
4,最後一點關於資料的東西
# 浮點數(有限迴圈小數,無限迴圈小數) != 小數 :有限迴圈小數,無限迴圈小數,無限不迴圈小數
# 浮點數
#354.123 = 3.54123*10**2 = 35.4123 * 10
# f = 1.781326913750135970
# print(f)
#通過結果我們可以看到:當小數特別長的話,就會發生偏差。
#原因:二進位制轉化會發生偏差
二進位制轉化
'''
進位制轉化:0 8 16
'''
print(bin(10))
print(oct(10))
print(hex(10))
輸出結果:
0b1010
0o12
0xa
#取絕對值
print(abs(-5))
print(abs(5))
輸出結果:
5
5
'''
Return the tuple (x//y, x%y).
'''
print(divmod(7, 2)) # div出發 mod取餘
print(divmod(9, 5)) # 除餘
'''
pow:Equivalent to x**y (with two arguments) or x**y % z (with three arguments)
'''
print(round(3.14159, 3))
print(pow(2, 3)) #pow冪運算 == 2**3
print(pow(2, 3, 3)) #冪運算之後再取餘
輸出結果:
(3, 1)
(1, 4)
3.142
8
2
寫到這裡有點累哦~~
LJ小姐姐 你好好看哦~