pyhton中的叠代器,生成器及函數式編程
#python中如何函數無返回值, 默認返回None;
def 函數名(形參)
函數體
return 返回值
函數名(實參)
#打印返回值
print 函數名
#定義了一個函數
def fun(*args): # 形式參數
print args
#調用函數
fun("python", 12, 0) # 實參
#必選參數
#默認參數
#可變參數----> *args args是元組類型
#關鍵字參數----->**kwargs kwargs是字典類型
函數的形式參數的默認值不要是可變參數;
def add_end(L=[]): # 默認參數 L = [1,2,3] L.append(‘END‘) # [1,2,3, ‘END‘] return L # return [1,2,3, ‘END‘] print add_end([1, 2, 3]) print add_end() print add_end() print add_end()
測試結果:
參數組合時: 必選 > 默認參數 > 可變參數 > 關鍵字參數
def fun(a, b=0, *c, **d):
print a, b, c, d
fun(1, 2, 4, 5, 6, 7, c=3, x=2, z=2)
測試結果:
測試練習:利用函數定義用戶管理系統
#!/usr/bin/env python #coding:utf-8 info = """" ###########user‘s administration########### 1.add user 2.login user 3.logout user 4.show users‘messages 5.exit """ userinfor = { ‘root‘: { ‘name‘: ‘root‘, ‘password‘: ‘root‘, ‘age‘: 18, ‘sex‘: 0, ‘email‘: ‘[email protected]‘ }, } def createUser(): user = raw_input("please input username:") if user in userinfor: print " %s exist!!!" % (user) else: password = raw_input("*please input password:") age = raw_input("*please input age:") sex = raw_input("please input sex:<0:male,1:female>") if not sex: sex = None email = raw_input("please input email:") if not email: email = None userinfor[user] = { ‘name‘: user, ‘password‘: password, ‘age‘: age, ‘sex‘: sex, ‘email‘: email } print "%s created!!!" % (user) def userLogin(): user = raw_input("please input your username:") if userinfor.has_key(user): password = raw_input("please input your password:") if userinfor[user][‘password‘] == password: print "%s logined" % (user) else: print "error:password doesn‘t match!!!" else: print "error:please create your username!!!" def userLogout(): user = raw_input("please input username:") if userinfor.has_key(user): password = raw_input("please input password:") if userinfor[user][‘password‘] == password: userinfor.pop(user) print "%s has delet" % (user) else: print "error:password doesn‘t match!!!" else: print "error:please input currect username!!!" def userView(): print userinfor.items() def main(): print info while 1: choice = raw_input("*please input your choice:") if choice == ‘1‘: createUser() elif choice == ‘2‘: userLogin() elif choice == ‘3‘: userLogout() elif choice == ‘4‘: userView() elif choice == ‘5‘: exit(0) else: print ‘error‘ if __name__ == "__main__": main()
測試結果:
利用函數判斷質數
輸入描述:輸入數字,判斷輸入數字以內的所有質數,並輸出。
def isPrime(n):
for i in range(2, n):
if n % i == 0:
return False
else:
return True
n = input(‘N:‘)
print [i for i in range(2,n) if isPrime(i)]
測試結果:
叠代器
#!/usr/bin/env python #coding:utf-8 list() import collections li = range(3) #iter()轉化li為叠代對象; it = li.__iter__() while True: try: print it.next() except StopIteration: Break
測試結果:
測試練習:斐波那契數列
計算的斐波那契數列前10項
#!/usr/bin/env python
#coding:utf-8
from collections import Iterable
class Fib(object):數列
def __init__(self):
self._a =0
self._b =1
def __iter__(self):
"ob.__iter__() <==> iter(ob)"
return self
def next(self):
self._a, self._b =self._b, self._a+self._b
return self._a
f = Fib()
for i,j in enumerate(f):
if i>9:
break
print j
測試結果:
生成器
1.生成器的第1種實現方式: 列表生成式改為生成器;
In [81]: [i for i in range(5)]
Out[81]: [0, 1, 2, 3, 4]
In [82]: (i for i in range(5))
Out[82]: <generator object <genexpr> at 0x1e58a00>
- return 和 yield的異同點:
#python中yield關鍵字
函數中如果有yield, 那麽調用這個函數的返回值為生成器。
當生成器g調用next方法, 執行函數, 知道遇到yield就停止;
再執行next,從上一次停止的地方繼續執行;
函數中遇return直接退出, 不繼續執行後面代碼;def fun(): print ‘a‘ return ‘b‘ print ‘c‘
print fun()
3.生成器的第2種實現方式;
def fib(max):
num1, num2 = 0, 1
for i in range(max):
yield num2
num1, num2 = num2, num1 + num2
g = fib(100000)
for i, j in enumerate(g):
if i > 10:
break
print j
生成器_無緩沖區的生產者消費者模型
#!/usr/bin/env python
#coding:utf-8
import time
import random
def consumer(name):
print "%s準備買粉條...... " %(name)
while True:
kind = yield
print "客戶[%s]購買了[%s]口味的粉條" %(name,kind)
c1 = consumer("jackson")
c1.next()
c1.send("微辣")
def producer(name):
c1 = consumer("roy")
c2 = consumer("jackson")
c1.next()
c2.next()
print "廚師[%s]準備制作粉條......" %(name)
for kind in ["微辣", "麻辣", "三鮮"]:
time.sleep(random.random())
print "[%s]制作了[%s]口味的粉條,賣給了用戶......" %(name,kind)
c1.send(kind)
c2.send(kind)
c1.close()
c2.close()
producer("lee")
測試結果:
![](http://i2.51cto.com/images/blog/201803/26/5fb59bcb00a7dd72b3626088bf920476.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
生成器_有緩沖區的生產者消費者模型
#!/usr/bin/env python
#coding:utf-8
import time
import random
cache = []
def consumer(name):
print "%s準備買粉條...... " %(name)
while True:
kind = yield
cache.remove(kind)
print "客戶[%s]購買了[%s]口味的粉條" %(name,kind)
def producer(name):
print "廚師[%s]準備制作粉條......" %(name)
for kind in ["微辣", "麻辣", "三鮮"]:
time.sleep(random.random())
print "[%s]制作了[%s]口味的粉條,賣給了用戶......" %(name,kind)
cache.append(kind)
producer("lee")
c1 = consumer(‘roy‘)
c1.next()
c1.send(‘微辣‘)
print "本店現有粉條口味:"
for i in cache:
print i
測試結果:
![](http://i2.51cto.com/images/blog/201803/26/1e190cb5fa2d0d63cded07d50b71794b.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
生成器_throw方法
#throw方法: 給生成器發送一個異常;
def gen():
while True:
try:
yield ‘a‘
yield ‘b‘
except TypeError:
print ‘Type Error‘
except ValueError:
print ‘value error‘
g = gen()
#print g.next()
print next(g) #g.next()<====>next(g)
g.throw(ValueError)
#print g.next()
print next(g)
運行結果:
![](http://i2.51cto.com/images/blog/201803/26/cd88fad54bee022325dfc4b14c164cd4.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
測試練習:迷你的聊天機器人
def chat_robot():
res = ‘‘
while True:
receive = yield res
if ‘hi‘ in receive:
res = "你好"
elif ‘name‘ in receive or ‘姓名‘ in receive:
res = "我是機器人小冰......"
elif ‘age‘ in receive or ‘年齡‘ in receive:
res = "年齡保密......"
else:
res = "我不太清楚你在說什麽,我還在學習中......"
Chat = chat_robot()
next(Chat)
while True:
send_data = raw_input("A>>: ")
if send_data == ‘q‘ or send_data == ‘quit‘:
print "機器人不和你玩了......"
break
response = Chat.send(send_data)
print "Robot>>: %s" %(response)
Chat.close()
測試結果:
![](http://i2.51cto.com/images/blog/201803/26/d9b106c8e25f889d4f6c978125a15e90.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
生成器的優勢總結:
1. 生成器提供了一種更為便利的產生叠代器的方式, 一般用戶不需要自己實現__iter__和next方法,
它默認返回一個可叠代對象;
2. 代碼更為簡潔,優雅;
函數式編程
函數作為實際參數傳給函數的函數稱為高階函數
函數名可以看作是變量名;
實際參數可以是函數, 返回值也可以是函數;這樣就稱為高階函數;
內置高階函數
map
In [85]: map(abs, [-1, 10, 20, 30, -100])
Out[85]: [1, 10, 20, 30, 100]
In [88]: def fun(x):
return x**2+100
....:
In [89]: map(fun, range(5))
Out[89]: [100, 101, 104, 109, 116]
reduce,第一個參數function,必須能接收兩個參數;
In [90]: def add(x, y):
....: return x + y
....: reduce(add, range(5))
....:
Out[90]: 10
階乘實現:
def jiecheng(x,y):
return x*y
while True:
n = input("N:")
print reduce(jiecheng,range(1,n+1))
測試結果:
![](http://i2.51cto.com/images/blog/201803/26/d9e37dfa4e28c4e8b48f65c348717913.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
匿名函數
1. 匿名函數的關鍵字為 lambda, 冒號前面是形式參數, 冒號後面是返回值;
2. 匿名函數的形式參數可以是: 必選, 默認, 可變, 關鍵字參數.
In [92]: f = lambda x, y=2, *args, *kwargs : (xy,args, kwargs)
In [93]: f(2,3,4,5,6,7, a=1, b=2, c=3)
Out[93]: (6, (4, 5, 6, 7), {‘a‘: 1, ‘b‘: 2, ‘c‘: 3})
filter,第一個參數function,返回值必須是Bool值;
In [94]: filter(lambda x: x % 2 == 0, range(1,20))
Out[94]: [2, 4, 6, 8, 10, 12, 14, 16, 18]
輸出200-300以內的質數
def isPrime(n):
for i in range(2, n):
if n % i == 0:
return False
else:
return True
li = range(200,301)
print filter(isPrime, li)
測試結果:
![](http://i2.51cto.com/images/blog/201803/26/c7dce5322e7825f44f090f9b410ad652.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
sorted 排序
由小到大排序
In [95]: sorted([91, 2, 23])
Out[95]: [2, 23, 91]
由大到小排序
In [96]: sorted([91, 2, 23], reverse=True)
Out[96]: [91, 23, 2]
忽略大小寫的排序
In [97]: users = [‘adam‘, ‘LISA‘, ‘barT‘, ‘Adam‘]
In [98]: def ignore_cmp(s1, s2):
....: s1 = s1.upper()
....: s2 = s2.upper()
....: return cmp(s1, s2)
....: sorted(users, cmp=ignore_cmp)
....:
Out[98]: [‘adam‘, ‘Adam‘, ‘barT‘, ‘LISA‘]
指定key值進行排序
goods = {
‘001‘: {
‘name‘: ‘computer‘,
‘price‘: 4000,
‘count‘: 20,
},
‘002‘: {
‘name‘: ‘apple‘,
‘price‘: 2,
‘count‘: 100
},
‘003‘: {
‘name‘: ‘xiaomi‘,
‘price‘: 2999,
‘count‘: 10
}
}
#根據價格進行排序, 打印出價格最高的商品名稱;
price_sorted_goods = sorted(goods.values(), key=lambda a : a[‘price‘])
print "價格最高的商品名稱為:", price_sorted_goods[-1][‘name‘]
#根據商品庫存進行排序, 打印出庫存最少的商品名稱和商品數量;
count_sorted_goods = sorted(goods.values(), key=lambda a : a[‘count‘])
print count_sorted_goods[0][‘name‘], count_sorted_goods[0][‘count‘]
測試結果:
![](http://i2.51cto.com/images/blog/201803/26/6692190192256f421932bd5bfc4074b9.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=)
pyhton中的叠代器,生成器及函數式編程