Python(八)高級特性

使用技巧

#!/usr/bin/env python
# coding:utf-8
def fun():
    return "hello"
    print "world"
#在函數裏面,遇到return,這個函數執行結束,return之後的語句不再執行,所以這裏直接調用函數不會輸出結果
fun()
#如果在調用的時候使用print+函數名,表示輸出函數的返回值,因此這裏會輸出返回值“hello”
print fun()


迭代(iteration)

判斷一個對象可迭代:

1.可以通過for循環來遍歷

Screenshot from 2017-12-28 09-49-53.png

2.通過collections模塊的iterable類型判斷

Screenshot from 2017-12-28 09-44-18.png

如果要對 list 實現類似 Java 那樣的下標循環怎麼辦:

python內置的枚舉方法enumerate,把一個 list 變成索引­元素對

Screenshot from 2017-12-28 10-08-53.png


列表生成式

for循環輸出結果(輸出1-10之間所有整數求平方之後的結果):

In [41]: [i**2 for i in range(1,11)]
Out[41]: [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
for循環+if語句(輸出1-10之間所有整數求平方,再跟2取餘爲0的結果):
In [42]: [i**2 for i in range(1,11) if (i**2)%2==0]
Out[42]: [4, 16, 36, 64, 100]
for循環+for循環(輸出'abc'和'123'的全排列):
In [46]: [i+j for i in "abc" for j in "123"]
Out[46]: ['a1', 'a2', 'a3', 'b1', 'b2', 'b3', 'c1', 'c2', 'c3']

擴展:

列出當前目錄下的所有.py文件或目錄:

In [8]: [i for i in os.listdir(".") if i.endswith(".py")]
Out[8]: ['xuehao.py', 'var_name_rule.py']
#os.listdir(".")表示列出當前目錄下所有文件、目錄

#i.endswith(".py")表示以.py結尾的

題目1:

給定一個正整數,編寫程序計算有多少對質數的和等於輸入的這個正整數,並輸出結果。輸
入值小於1000。
如,輸入爲10, 程序應該輸出結果爲2。(共有兩對質數的和爲10,分別爲(5,5),(3,7))

解答:

#!/usr/bin/env python
# coding:utf-8
shuru=input("輸入一個正整數(<=1000):")
def zhishu(num):
    for i in range(2,num):
        if num%i == 0:
            return False
    else:
        return True

p=[i for i in range(2,shuru) if zhishu(i)]

peidui=[(m,n) for m in p for n in p if m+n == shuru and m <= n]
print len(peidui)

生成器

一、簡介

1.背景

通過列表生成式,我們可以直接創建一個列表:

Screenshot from 2017-12-30 17:26:54.png

受到內存限制,列表容量肯定是有限的,例如創建一個包含 100 萬個元素的列表,會佔用很大的存儲空間,創建過程有可能使電腦卡住。

2.定義

在循環的過程中不斷由前一個元素推算出後一個元素,但是後續元素並不立刻生成出來。這樣就不必創建完整的 list,從而節省大量的空間。在 Python 中,這種一邊循環一邊計算的機制,稱爲生成器(Generator)

3.使用生成器的方法

(1.)把一個列表生成式的 [] 改成 ()

>>> g = (i for i in range(1,10000000))
>>> g
<generator object <genexpr> at 0x7f13a59d97d0>

調用:

 - 使用.next()每調用一次顯示一個元素

Screenshot from 2017-12-30 17:21:58.png

 - 使用for循環

Screenshot from 2017-12-30 17:25:10.png

(2.)yield

如果函數裏面有yield關鍵字,那麼調用這個函數的結果賦值給的變量爲生成器

當生成器g調用第一個next方法時,會運行函數,直到遇到第一個yield停止

當調用第二個next方法時,會從停止的地方繼續執行,直到遇到下一個yield

#!/usr/bin/env python
# coding:utf-8
def fun():
    print "1."          #輸出"1."
    yield "第一個yield"  #遇到yield停止,yield後面跟的內容可以在print g.next()時顯示出來
    print "2."
    yield "第二個yield"
    print "3."
    yield "第三個yield"
    print "4."
    yield "第四個yield"

g = fun()

print g.next()
print g.next()
print g.next()
print g.next()

執行結果:

[root@python code5]# python test.py
1.
第一個yield
2.
第二個yield
3.
第三個yield
4.
第四個yield

題目1:

Fibonacci(斐波納契)數列,除第一個和第二個數外,任意一個數都可由前兩個數相加得到:1, 1, 2, 3, 5, 8, 13, 21,...,本題要求生成6個數即可

解答:

#!/usr/bin/env python
# coding:utf-8
def fib(max):    #max爲最終生成fib數列個數
    n,a,b = 0,0,1   #n代表當前fib數列個數,a代表n-1的值,b代表n的值
    while n < max:
        yield b     #當前第一個數列
        a,b = b,a+b
        n += 1

g = fib(6)   #變量g就是生成器

print g.next()
print g.next()
print g.next()
print g.next()
print g.next()
print g.next()

(3.)send用法

使用send方法給生成器函數發送數據

使用send方法前,必須先調用一次next()方法

遇到下一個yield停止

#!/usr/bin/env python
# coding:utf-8
def fun():
    print "bbbb"
    num1 = yield
    print num1
    num2 = yield
    print num2

g = fun()   #g是生成器

g.next()    #使用send方法前,必須先調用一次next()方法
g.send(1)   #將1發送給變量num1,此時num1=1
g.send(11)  #將11發送給變量num1,此時num1=11

執行結果:

Screenshot from 2017-12-30 19:14:26.png

題目2:

生產者-消費者(producer-consumer)模型,也稱作有界緩衝區(bounded-buffer)問題,兩個進程共享一個公共的固定大小的 緩衝區。其中一個是生產者,用於將消息放入緩衝區;另外一個是消費者,用於從緩衝區中取出消息。問題出現在當緩衝區已經滿了,而此時生產者還想向其中放入 一個新的數據項的情形,其解決方法是讓生產者此時進行休眠,等待消費者從緩衝區中取走了一個或者多個數據後再去喚醒它。同樣地,當緩衝區已經空了,而消費 者還想去取消息,此時也可以讓消費者進行休眠,等待生產者放入一個或者多個數據時再喚醒它。

解答:

#!/usr/bin/env python
# coding:utf-8
import time  #調用time內置模塊
food = []    #定義一個food列表,模擬包子店的所有包子
def consumer(name):
    print "%s準備買包子" %(name)
    while True:
        baozi_name = yield
        print "客戶[%s]買了[%s]餡的包子" %(name,baozi_name)
        food.remove(baozi_name)  #當客戶買了這個餡的包子就從列表中刪除

def producer(name,*kind):  #*kind表示使用函數中的可變參數
    c1 = consumer("客戶1")
    c1.next()
    print "準備製作包子..."
    for i in kind:
        time.sleep(1)  #表示休眠一秒,模擬廚師製作包子過程
        print "廚師[%s]做了[%s]餡包子" %(name,i)
        food.append(i)  #廚師製作了這個餡的包子就在列表中加入
        c1.send(i)

producer("白鬍子","牛肉","韭菜","豆沙")

題目3:

簡易聊天機器人

解答:






發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章