1. 程式人生 > >Python全棧(第一期)Day15

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小姐姐 你好好看哦~