Python核心程式設計v2.0 第11章習題答案

史前大洪水發表於2017-09-06

1.
input = 2:ERROR ; 2,3,4 ; 2,3,4
input = 4 : ERROR ; 4 ;4
input = 5 : ERROR ; None ; None

2.
不明白啥是產物,故保留了加法式子

# -*- coding: utf-8 -*-
def fun1(li,li2):
    re = {}
    for i in range(len(li)):
        re[str(li[i])+'+'+str(li2[i])] = li[i]+ li2[i]
    return  re


if __name__ == '__main__':
    li =  [1,2,3,4]
    li2 = [5,6,7,8]
    re = fun1(li,li2)
    for eachkey in re:
        print eachkey,re[eachkey]

結果:

4+8 12
2+6 8
3+7 10
1+5 6

3.
a,b寫在一起了,b用到了非關鍵字可變長引數來接收當輸入是引數集合的情況

# -*- coding: utf-8 -*-
def max2(num,num2):
    if num >= num2:
        return num
    else:
        return num2

def min2(num,num2):
    if num <= num2:
        return num
    else:
        return num2

def my_max(lis,*therest):
    #判斷傳入的引數1是不是list,按list比較
    if isinstance(lis,list):
        temp = lis[0]
        for i in lis:
            if temp < i:
                temp = i
        return temp
    #傳入的是引數集合,按引數集合比較
    else:
        temp = lis
        for i in therest:
            if temp < i:
                temp = i
        return temp


def my_min(lis,*therest):
    if isinstance(lis,list):
        temp = lis[0]
        for i in lis:
            if temp > i:
                temp = i
        return temp
    else:
        temp = lis
        for i in therest:
            if temp > i:
                temp = i
        return temp

if __name__ == '__main__':
    print my_max([1,3,4,5])
    print my_min([2,4,1,7])
    print my_max(['wqe','rd','wes'])
    print my_max(1,3,4,2)

4.

# -*- coding: utf-8 -*-
def turning(fen):
    h = fen / 60
    m = fen % 60
    return h,m
if __name__ == '__main__':
    fen = 75
    (h,m) = turning(fen)
    print h,m

5.
設定一個預設引數即可,形如tax = 0.75

6.
翻譯過來的中文怎麼看著這麼奇怪,經常不能理解到底在說啥。

# -*- coding: utf-8 -*-
def turning(s,*arg):
    #注意不要寫成字串形式了
    print s % arg

if __name__ == '__main__':
    turning('%d and %d',7,9)

7.

if __name__ == '__main__':
    li1 = [1,2,3]
    li2 = ['a','b','c']
    li3 = []
    map(lambda x,y:li3.append((x,y)),li1,li2)
    print zip(li1,li2)

8.

# -*- coding: utf-8 -*-
def func(year):

    if year % 4 == 0 and year % 100 != 0:
        return 1
    elif year % 400 == 0:
        return 1
    else:
        return 0

if __name__ == '__main__':
    list = [2010,2016,1994]
    li = filter(func,list)
    li2 = [n for n in list if func(n) == 1]

9.
reduce的效果是list[0]與list[1]經過func 產生一個結果,然後這個結果再和list[3]進行func,依次向後進行

# -*- coding: utf-8 -*-
def average(num):
    su = reduce(lambda x, y: x + y, num)
    ave = su/len(num)
    return  ave
if __name__ == '__main__':
    num = [1,2,3,4,5]
    print average(num)

10.
os.listdir 列出指定目錄的檔案,filter返回不包括這兩個特殊目錄的其餘檔案

11.

# -*- coding: utf-8 -*-
def cleanfile(lines):
    li = map(lambda x:x.strip(),lines)
    #列表解析
    #li = [x.strip() for x in lines]
    return li

if __name__ == '__main__':
    order = raw_input('new or old')
    name = raw_input('filename')
    f = open(name, 'r')
    lines = f.readlines()
    f.close()
    li = cleanfile(lines)

    if order == 'new':
        file2 = raw_input('newfile')
    else:
        file2 = name
    f = open(file2, 'w')
    for i in li:
        f.write(i)
        f.write('\n')
    f.close()

12.
time.clock返回當前的cpu時間

# -*- coding: utf-8 -*-
import time
def testit(func,*arg):
    t0 = time.clock()
    re = func(*arg)
    t1 = time.clock()-t0
    return re,t1

if __name__ == '__main__':
    funcs = (int,float)
    vals = ('123',123)

    for eachfunc in funcs:
        print '__________'
        for eachval in vals:
            retval = testit(eachfunc,eachval)
            print 'result: ',retval[0]
            print 'time:',retval[1]

13.

# -*- coding: utf-8 -*-
import time

def mult(x,y):
    return x*y

def factorial(n):
    if n == 0 or n == 1:
        return 1
    else:
        return (n*factorial(n-1))

def testit(func,*arg):
    t0 = time.clock()
    re = func(*arg)
    t1 = time.clock()-t0
    return re,t1

if __name__ == '__main__':
    li = range(1,6)
    # re = reduce(mult,li)
    re = testit(reduce,mult,li)

    # re2 = reduce(lambda x,y:x*y,li)
    re2 = testit(reduce,lambda x,y:x*y,li)

    # re3 = factorial(5)
    re3 = testit(factorial,5)
    print re
    print re2
    print re3

結果:
lambda的用時應該是最少的

(120, 5.598383186935613e-06)
(120, 9.33063864489268e-07)
(120, 1.555106440815449e-06)

14.

# -*- coding: utf-8 -*-

def f(n):
    if n == 1:
        return 1
    elif n == 2:
        return 1
    else:
        return f(n-1)+f(n-2)


if __name__ == '__main__':
    print f(5)

15.
f 接收開始列印的位置

# -*- coding: utf-8 -*-

def f(n):
    #如當前n未到末尾則列印當前並從n+1位置再進行函式
    if n + 1< len(str):
        print str[n]
        f(n+1)
    #已到達字串末尾
    else:
        print str[n]


if __name__ == '__main__':
    str = 'this is a string'
    f(0)

16.
除法用的真實除法,單獨做了處理

# -*- coding: utf-8 -*-
from __future__ import  division
from operator import add,sub,mul
from random import randint,choice

ops = {'+':add,'-':sub,'*':mul}

def doprob():
    op = choice('+-*/')
    nums = [randint(1,10) for i in range(2)]
    nums.sort(reverse=True)

    if op == '/':
        ans = nums[0]/nums[1]

    else:
        ans = ops[op](*nums)

    print '%d %s %d' % (nums[0],op,nums[1])
    print '= ',ans

if __name__ == '__main__':
    doprob()

17.
a)currying:將函數語言程式設計的概念與預設引數以及可變引數結合在一起,一個帶n個引數,curried的函式固化第一個引數為固定引數,並返回一個帶n-1個引數的函式物件。
currying能泛化成為PFA。PFA將任意數量的引數的函式轉化為另一個帶剩餘引數的函式物件
b)閉包:如果在一個內部函式裡,對在外部作用域(但不是全域性作用域)的變數進行引用,則內部函式就被認為是閉包。閉包和函式呼叫沒什麼關係,而是關於使用定義在其他作用域的變數。
c)生成器:掛起返回出中間值並多次繼續的協同程式
迭代器:呼叫獲得下個元素next()

18.

# -*- coding: utf-8 -*-
import threading
import time

lock = threading.Lock()
su = 100


def deco(func):
    def _deco(money):
        lock.acquire()
        ret = func(money)
        lock.release()
        return ret
    return _deco

@deco
def funk(money):
    global su
    su = su + money
    return su



class MyThread(threading.Thread):  # 使用類定義thread,繼承threading.Thread
    def __init__(self, name):
        threading.Thread.__init__(self)
        self.name = "Thread-" + str(name)

    def run(self):  # run函式必須實現
        global lock # 多執行緒是共享資源的,使用全域性變數
        # time.sleep(1)

        # if lock.acquire(): # 當需要獨佔counter資源時,必須先鎖定,這個鎖可以是任意的一個鎖,可以使用上邊定義的3個鎖中的任意一個
        money = funk(100)
        print "I am %s, set counter:%s" % (self.name, money)
        print '\n'
        # lock.release()  # 使用完counter資源必須要將這個鎖開啟,讓其他執行緒使用
        # print lock.release()



if __name__ == '__main__':
    for i in xrange(1,5):
        my_thread = MyThread(i)
        my_thread.start()

在我機子上執行沒出現阻塞及搶佔的情況,在去掉release語句後,則只有thread 1 獲得了資源永久阻塞,原理應該沒錯。
裝飾器我現在的理解大概是在處理呼叫某函式時,自動做一些事情,並在函式結束後也可以設定再做一些處理。

相關文章