5-14 練習題及答案
一. 回答題
1. 寫出Python查找一個變量的順序 提示:4中作用域的順序
本地作用域(Local)→當前作用域被嵌入的本地作用域(Enclosing locals)→全局/模塊作用域(Global)→內置作用域(Built-in)
2. Python裏的拷貝,打印結果並解釋。
import copy
a = [1, 2, 3, 4, [‘a‘, ‘b‘]] #原始對象
b = a #賦值,傳對象的引用
c = copy.copy(a) #對象拷貝,淺拷貝
d = copy.deepcopy(a) #對象拷貝,深拷貝
a.append(5) #修改對象a
a[4].append(‘c‘) #修改對象a中的[‘a‘, ‘b‘]數組對象
print(‘a = ‘, a)
print(‘b = ‘, b)
print(‘c = ‘, c)
print(‘d = ‘, d)
a = [1, 2, 3, 4, [‘a‘, ‘b‘, ‘c‘], 5]
b = [1, 2, 3, 4, [‘a‘, ‘b‘, ‘c‘], 5]
c = [1, 2, 3, 4, [‘a‘, ‘b‘, ‘c‘]]
d = [1, 2, 3, 4, [‘a‘, ‘b‘]]
3. 打印代碼的值,並解釋其原因。
a = 1
def fun(a):
a = 2
return a
print(fun(a))
print(a)
# 2 1
4. 打印代碼的值,並解釋其原因。
a = []
def fun(a):
a.append(1)
return a
print(fun(a))
print(a)
# [1] [1]
5. L = [x*x for x in range(10)] 和 g = (x*x for x in range(10))的結果分別為:
# [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] <generator object <genexpr> at 0x0000028F8B774200>
6. 將列表生成式中[]改成() 之後數據結構是否改變?請說明原因。
是,從列表變為生成器
通過列表生成式,可以直接創建一個列表。但是,受到內存限制,列表容量肯定是有限的。而且,創建一個包含百萬元素的列表,不僅是占用很大的內存空間,如:我們只需要訪問前面的幾個元素,後面大部分元素所占的空間都是浪費的。因此,沒有必要創建完整的列表(節省大量內存空間)。在Python中,我們可以采用生成器:邊循環,邊計算的機制—>generator
7. 創建一個閉包必須滿足那些條件:
1.必須有一個內嵌函數
2.內嵌函數必須引用外部函數中的變量
8. 通過函數化編程實現5的階乘 提示:在函數中使用遞歸 例如函數中傳入5,計算出5*4*3*2*1的結果
def func(n):
if n == 1:
return 1
else:
return n * func(n - 1)
obj = func(3)
print(obj)
9. 為此函數加裝飾器
def foo():
print(‘hello foo‘)
(1)為此函數加一個裝飾器,執行對應函數內容後,將當前時間寫入一個文件做一個日誌記錄。
(2)改成參數裝飾器,即可以根據調用時傳的參數決定是否記錄時間,比如@logger(True)
import time
def init(func):
def wrapper(*args,**kwargs):
a= str(time.time()) + "執行%s\n" % func
with open("record.txt","a+") as f:
f.write(a)
func(*args,**kwargs)
return wrapper
@init
def foo():
print(‘hello foo‘)
return()
foo()
import time
def auth(flag):
def init(func):
def wrapper(*args,**kwargs):
if flag == True:
a= str(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())) + "執行%s\n" % func
with open("record.txt","a+") as f:
f.write(a)
func(*args,**kwargs)
return wrapper
return init
@auth(True)
def foo():
print(‘hello foo‘)
foo()
10. 寫函數,將字典作為參數傳進函數,檢查傳入字典的每一個value的長度,如果大於2,那麽僅保留前兩個長度的內容,並將新內容返回給調用者。PS:字典中的value只能是字符串或列表
dic = {"k1": "v1v1", "k2": [11,22,33,44]}
def my_dict(dic):
for key in dic:
if len(dic[key]) > 2:
dic[key] = dic[key][0:2]
else:
continue
return dic
dic = {"k1": "v1v1", "k2": [11,22,33,44]}
res = my_dict(dic)
print(res)
11. 寫函數,檢查獲取傳入列表或元組對象的所有奇數位索引對應的元素,並將其作為新列表返回給調用者。
def my_fun(func):
my_count = 0
func1 = []
for i in func:
my_count = my_count + 1
if my_count % 2 == 0:
func1.append(i)
print(func1)
my_fun([1,2,3,‘edj‘])
12. 使用內置函數將 a="1234" 變為 [1, 2, 3, 4]
list(map(int, ‘1234‘))
13. 使用內置函數對obj = [25, 9, -23, 9, -11]按絕對值大小排序。
sorted(obj,key=abs)
14. 1)提供2017-11-1 2017-11-30 打印出他們之間的日期
例如:2017-11-01
2017-11-02
2017-11-03
import time
start_time = time.mktime(time.strptime("2017-11-01","%Y-%m-%d"))
end_time = time.mktime(time.strptime("2017-12-01","%Y-%m-%d"))
while start_time <= end_time:
print(time.strftime("%Y-%m-%d",time.localtime(start_time)))
start_time += 86400.0
2)打印出 2017-11-1 2017-11-30的之間日期,並打印出各自對應的星期。
例如:2017-12-01 星期五
2017-12-02 星期六
2017-12-03 星期日
import time
start_time = time.mktime(time.strptime("2017-12-01","%Y-%m-%d"))
end_time = time.mktime(time.strptime("2018-1-17","%Y-%m-%d"))
w_dic = {"0":"星期日","1":"星期一","2":"星期二","3":"星期三","4":"星期四","5":"星期五","6":"星期六"}
while start_time <= end_time:
date_num_mode = time.strftime("%Y-%m-%d %w",time.localtime(start_time))
date_ymd,date_w = date_num_mode.split(" ")
print(date_ymd,w_dic[date_w])
start_time += 86400.0
15. 使用生成器編寫foo函數,調用該函數foo(21)產生如下結果(斐波那契數列),1,1,2,3,5,8,13,21
def fib(max):
a = 0
b = 1
while b<=max:
yield b
b,a = a+b,b
for i in fib(21):
print(i,end=‘ ‘)
16. 讀取文件a.txt,匹配文中所有ip地址,將所有ip地址加入到一個列表中,打印該列表。
import re
li = []
with open("a","r") as f:
for line in f:
result = re.findall(r‘\d+\.\d+\.\d+\.\d+‘, line)
if result:
li += result
print(li)
17. s = ‘123.33sdhf3424.34fdg323.324‘,計算字符串中所有數字的和
本題結果應為:123.33+3424.34+323.32
import re
s = ‘123.33sdhf3424.34fdg323.324sss12‘
obj = re.findall(r‘\d+\.\d+|\d+‘,s)
start = 0
for i in obj:
start += float(i)
print(start)
18. 正則替換:
1.將字符串中所有的數字換為大寫字母A, 結果為 aakkAdddAkkA
result=aakk123ddd55kk66
print(re.sub("\d+","A",result))
2.將字符串的前4位數字轉換為A
print(re.sub("\d","A",result,4))
19. 利用random模塊隨機生成四位驗證碼,包括字母和數字
import random
checkcode = ‘‘
for i in range(4):
current = random.randrange(0,4)
if current != i:
temp = chr(random.randint(65,90))
else:
temp = random.randint(0,9)
checkcode += str(temp)
print(checkcode)
20. 如下,每個小字典的name對應股票名字,shares對應多少股,price對應股票的價格,用filter過濾出,單價大於100的股票有哪些
portfolio = [
{‘name‘: ‘IBM‘, ‘shares‘: 100, ‘price‘: 91.1},
{‘name‘: ‘AAPL‘, ‘shares‘: 50, ‘price‘: 543.22},
{‘name‘: ‘FB‘, ‘shares‘: 200, ‘price‘: 21.09},
{‘name‘: ‘HPQ‘, ‘shares‘: 35, ‘price‘: 31.75},
{‘name‘: ‘YHOO‘, ‘shares‘: 45, ‘price‘: 16.35},
{‘name‘: ‘ACME‘, ‘shares‘: 75, ‘price‘: 115.65}
]
name = list(filter(lambda x:x["price"] > 100,portfolio))
print(name)
21. 怎麽理解叠代器和生成器?生成器有什麽特點?
22. 函數的形參有哪幾種方式,各自在什麽情況下使用以及存放順序?
23. 如下輸出以下函數的執行結果
def foo(a1, args = []):
print("args before = %s" % (args))
args.insert(0, 10)
args.insert(0, 99999)
print("args = %s " % (args))
def main():
foo(‘a‘)
foo(‘b‘)
if __name__ == "__main__":
main()
args before = []
args = [99999, 10]
args before = [99999, 10]
args = [99999, 10, 99999, 10]
24. 解釋一下是否會報錯,原因是什麽?要是不報錯打印什麽值?報錯的可以怎麽改就不報錯
1).
def test():
print(luffy)
luffy = "the king of sea."
2).
def test():
print(luffy)
luffy = ‘e‘
luffy = "the king of sea."
3).
def test():
luffy = ‘e‘
print(luffy)
luffy = "the king of sea."
4).
def func(a,**kwargs):
print(kwargs)
print(a)
for k,v in kwargs.items():
print(k,v)
func({"name":"alex"})
結果:{‘name‘: ‘alex‘}
{}
name alex
25. 實現9*9乘法口訣表
for i in range(1,10):
for j in range(1,10):
print(j, "x", i, "=", i * j,"\t",end="")
if i==j:
print("")
break
5-14 練習題及答案