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()

測試結果:
pyhton中的迭代器,生成器及函數式編程

參數組合時: 必選 > 默認參數 > 可變參數 > 關鍵字參數

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)

測試結果:
pyhton中的迭代器,生成器及函數式編程

測試練習:利用函數定義用戶管理系統

#!/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()

測試結果:
pyhton中的迭代器,生成器及函數式編程

利用函數判斷質數
輸入描述:輸入數字,判斷輸入數字以內的所有質數,並輸出。

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)]

測試結果:
pyhton中的迭代器,生成器及函數式編程

迭代器

#!/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

測試結果:
pyhton中的迭代器,生成器及函數式編程

測試練習:斐波那契數列
計算的斐波那契數列前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

測試結果:
pyhton中的迭代器,生成器及函數式編程

生成器
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>
  1. 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")

測試結果:
pyhton中的迭代器,生成器及函數式編程

生成器_有緩衝區的生產者消費者模型

#!/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

測試結果:
pyhton中的迭代器,生成器及函數式編程

生成器_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)

運行結果:
pyhton中的迭代器,生成器及函數式編程

測試練習:迷你的聊天機器人

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()

測試結果:
pyhton中的迭代器,生成器及函數式編程

生成器的優勢總結:

  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))

測試結果:
pyhton中的迭代器,生成器及函數式編程

匿名函數

  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)

測試結果:
pyhton中的迭代器,生成器及函數式編程

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']

測試結果:
pyhton中的迭代器,生成器及函數式編程

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