Python-日志-day10-2019-08-02

day9-函數(shù)

一.匿名函數(shù)

1.匿名函數(shù)

匿名函數(shù)就是沒有函數(shù)名的函數(shù);匿名函數(shù)可以看成是類名是function的值和10,‘a(chǎn)bc’是同類東西
注意:匿名函數(shù)本質(zhì)還是函數(shù),函數(shù)中除了聲明語法以外其他的都使用匿名函數(shù)
(1)語法
lambda 參數(shù)列表:返回值
(2)說明
lambda - 關(guān)鍵字
函數(shù)名 = 參數(shù)列表 - 參數(shù)名1,參數(shù)名2,....
:-固定
返回值 - 任何有結(jié)果的表達(dá)式;它是匿名函數(shù)的函數(shù)體,相當(dāng)于普通函數(shù)中的return語句
調(diào)用匿名函數(shù):保存匿名數(shù)值的變量(實參列表)
(3)參數(shù)
普通函數(shù)中除了用'參數(shù)名:類型'的形式來指定參數(shù)類型以外,其他的語法匿名函數(shù)'都支持

# def 函數(shù)名(參數(shù)列表):
#     函數(shù)體
fn1 = lambda x, y: x+y
"""
def fn1(x, y):
    # x=10, y = 30
    return x+y
"""
fn2 = lambda x: print('====')
"""
def fn2(x):
    return print('=====')
"""

print(fn1(10, 30))
print(fn2(10))

100   # int類型的數(shù)據(jù)
'abc'  # str類型的數(shù)據(jù)
[1, 2, 3]   # list類型的數(shù)據(jù)
{'a': 10, 'b': 20}    # dict類型的數(shù)據(jù)
lambda x: x   # function類型的數(shù)據(jù)

a = 100
str1 = 'abc'
list1 = [1, 2, 3]
dict1 = {'a': 10, 'b': 20}
fn1 = lambda x: x
print(a + 10, str1.replace('a', 'A'), list1[0], fn1(90))

list2 = [100, 'abc', [1, 2, 3], lambda x: x*2]
print(list2)
print(list2[0] * 10)
print(list2[1][0])
print(list2[-1](12))


sum1 = lambda x, y, z=3: x+y+z
sum3 = lambda *nums: sum(nums)

def sum2(x, y, z=0):
    return x+y+z

print(sum2(10 , 30), sum2(y=20, x=10))
print(sum1(1, 2), sum1(y=2, x=1))
print(sum3(1, 2, 3, 4, 5))

二.變量的作用域

1.變量的作用域:

變量在程序中能夠使用的范圍

2.全局變量和局部變量

(1)全局變量
沒有聲明在函數(shù)里面或者類里面的變量就是全局變量
作用域:從聲明開始到文件結(jié)束的任何位置
(2)局部變量
聲明在函數(shù)中的變量就是局部變量(函數(shù)的參數(shù)也是聲明在函數(shù)中的變量,比如形參)
作用域:從聲明開始到函數(shù)結(jié)束的任何位置
(3)函數(shù)調(diào)用過程(內(nèi)存):壓棧
當(dāng)調(diào)用函數(shù)的時候,系統(tǒng)會自動在內(nèi)存的棧區(qū)間為這個函數(shù)開辟一個獨立的內(nèi)存區(qū)域,用來保存在函數(shù)中聲明的變量。當(dāng)函數(shù)調(diào)用結(jié)束,這個內(nèi)存區(qū)域會自動釋放。

print('==============全局變量================')
a = 10   # 全局變量

# x是全局變量
for x in range(5):
    if False:
        c = 100
    b = 20   # 全局變量
    print('循環(huán)里面:', a)
    print('循環(huán)里面:', x)

print('外面:', b)

def func1():
    print('函數(shù)里面:', a)
    print('函數(shù)里面:', x)
    print('函數(shù)里面:', b)


func1()

print('===================局部變量===================')


def func2(x1=10, y1=20):
    z1 = 100
    print('函數(shù)內(nèi)部:', x1, y1, z1)


func2()


# print('函數(shù)外部:', x1)   # NameError: name 'x1' is not defined
# print('函數(shù)外部:', z1)   # NameError: name 'z1' is not defined

3.global和nonlocal

global和nonlocal是函數(shù)中的關(guān)鍵字,和return一樣只能在函數(shù)體中使用
(1)global - 在函數(shù)中聲明一個全局變量
global 變量
變量 = 值

(2)nonlocal
在局部的局部中去修改局部變量的值
nonlocal 變量
變量 = 值

print('=============global=============')
a1 = 111
b1 = 100


def func3():
    # 這兒是在聲明一個局部變量a1
    a1 = 222
    print('函數(shù)里面a:', a1)

    # 這兒的b1是全局變量
    global b1
    b1 = 333
    print('函數(shù)里面b:', b1)


func3()

print('函數(shù)外面a:', a1)
print('函數(shù)外面b:', b1)

print('================nonlocal=============')


def func4():
    a2 = 100

    def func5():
        nonlocal a2
        a2 = 500
        print('函數(shù)里面的函數(shù)里面a2:', a2)

    func5()

    print('函數(shù)里面a2:', a2)


func4()
# print(a2)    # NameError: name 'a2' is not defined



def func(str):
    # str = 'abc'
    sum = 0

func('hello world!')

print(str(100))

三.函數(shù)遞歸

1.什么是遞歸函數(shù)

自己調(diào)用自己的函數(shù)(函數(shù)體中調(diào)用當(dāng)前函數(shù))
循環(huán)能做的事情,遞歸都可以做
注意:能用循環(huán)解決的問題就不要用遞歸

# def func1():
#     print('=====')
#     func1()
#
#
# func1()`

2.怎么寫遞歸

第一步:找臨界值(循環(huán)結(jié)束的條件)在這兒需要結(jié)束函數(shù)
第二步:找關(guān)系 - 找f(n)和f(n-1)的關(guān)系(找當(dāng)次循環(huán)和上次循環(huán)的關(guān)系)
第三步:假設(shè)函數(shù)的功能已經(jīng)實現(xiàn),根據(jù)關(guān)系用f(n-1)去實現(xiàn)f(n)的功能

# 用遞歸函數(shù)實現(xiàn): 1+2+3+...+n
def sum1(n):
    # 第一步: 找臨界值
    if n == 1:
        return 1
    # 第二步: sum1(n)和sum1(n-1)
    # sum1(n) == 1+2+3+...+n-1+n
    # sum1(n-1) == 1+2+3+ ... + n-1
    # sum1(n) = sum1(n-1) + n
    return sum1(n-1)+n


print(sum1(100))


# 用遞歸函數(shù)求斐波那契數(shù)列中第n個數(shù): 1, 1, 2, 3, 5, 8, 13, 21,...
def sequence(n):
    if n == 1 or n == 2:
        return 1
    # 找關(guān)系:sequence(n)和sequence(n-1)
    # sequence(n) = sequence(n-1) + sequence(n-2)
    return sequence(n-1) + sequence(n-2)


print(sequence(1), sequence(2))
print(sequence(8))

# 練習(xí): 用遞歸實現(xiàn)以下功能
"""
n = 5
*****
****
***
**
*

n=4
****
***
**
*
"""


def print_star(n):
    if n == 1:
        print('*')
        return
    # 找關(guān)系: 打印n個*, 再實現(xiàn)f(n-1)的功能
    print(n * '*')
    print_star(n-1)


print_star(3)


# 練習(xí): 用遞歸實現(xiàn)以下功能
"""
n=3
*
**
***

n=4
*
**
***
****
"""

四.迭代器

1.迭代器(iter)

迭代器作為容器可以保存多個數(shù)據(jù);數(shù)據(jù)的來源:
(1)將其他序列轉(zhuǎn)化成迭代器
(2)生成器

# 1)將其他序列轉(zhuǎn)換成迭代器
iter1 = iter('abc')
print(iter1, type(iter1))

iter2 = iter([12, 30, 90])
print(type(iter2))

2.獲取元素

不管用哪種方式去獲取了元素的值,那么這個元素在迭代器中就不存在了
(1)獲取單個元素:next(迭代器),迭代器.next() --->獲取迭代器中的第一個元素
(2)遍歷:
for 變量 in 迭代器:

iter3 = iter('hello')
print(next(iter3))
print(next(iter3))
print(next(iter3))
print(iter3.__next__())

# for x in range(100):
#     print(x)

print(next(iter3))
# print(next(iter3))   # StopIteration  如果迭代器為空,用next獲取元素的時候會報錯

iter4 = iter('world')
for x in iter4:
    print(x)

# print(next(iter4))    # StopIteration

print('===============')
iter4 = iter('world')
print(next(iter4))

for x in iter4:
    print('循環(huán):', x)

五.生成器

1.什么是生成器

(1)生成器就是迭代器中的一種;
(2)調(diào)用一個帶有yield關(guān)鍵字的函數(shù)就可以得到一個生成器
如果一個函數(shù)中有yield的關(guān)鍵字:
a. 調(diào)用函數(shù)不會執(zhí)行函數(shù)體
b.函數(shù)調(diào)用表達(dá)式的值不是函數(shù)的返回值而是一個生成器對象

# 1.怎么去創(chuàng)建一個生成器
def func1():
    print('=======')
    if False:
        yield
    return 100


gen1 = func1()    # 這兒的gen1就是一個生成器對象
print('外部:', gen1)

2.生成器產(chǎn)生數(shù)據(jù)的原理

(1)一個生成器能夠產(chǎn)生多少數(shù)據(jù),就看執(zhí)行完生成器對應(yīng)的函數(shù)的函數(shù)體會遇到幾次yield
yield后面的值就是生成器能夠產(chǎn)生的數(shù)據(jù)
(2)每次獲取生成器中的元素的時候,都是先去執(zhí)行函數(shù)體,直到遇到y(tǒng)ield,并且將yield后面的值作為元素的結(jié)果,并且保留結(jié)束的位置,下次獲取下一個值的時候,從上次結(jié)束的位置接著執(zhí)行函數(shù)體,直到遇到y(tǒng)ield。如果從開始執(zhí)行到函數(shù)結(jié)束,都沒有遇到y(tǒng)ield,就會報錯stopIteration錯誤

print('================2==========')


def func2():
    print('+++++')
    yield 1
    print('-----')
    yield 100     # yield 后邊可以跟數(shù)據(jù);同一個函數(shù)可以有多個yield


gen2 = func2()
print(gen2)

print('函數(shù)外部:', next(gen2))
print('函數(shù)外部:', next(gen2))
# print('函數(shù)外部:', next(gen2))   # StopIteration


def func3():
    print('第一段代碼')
    yield
    print('第二段代碼')
    yield
    print('第三段代碼')
    yield


gen3 = func3()

time.sleep(1)
next(gen3)
time.sleep(1)
next(gen3)
time.sleep(1)
next(gen3)


# 練習(xí):
def func4():
    # x = 0
    for x in range(0, 100, 3):
        yield x


print(next(func4()))
print(next(func4()))
print(next(func4()))
gen4 = func4()
print(next(gen4))   # 0
print(next(gen4))   # 3
print(next(gen4))

六.生成式


# 1.生成式
"""
生成式就是生成器的簡寫

1)語法一
生成器 = (表達(dá)式 for 變量 in 序列)   

a.說明: 表達(dá)式  -  任何有結(jié)果的語句; 數(shù)據(jù),賦值后的變量,非賦值的運算表達(dá)式等...
b.展開成生成器:
def 函數(shù)名():
    for 變量 in 序列:
        yield 表達(dá)式      
生成器 = 函數(shù)名()


"""
# 1.用生成式創(chuàng)建生成器
gen = (x*2 for x in 'hello')
print(type(gen))   # <class 'generator'>
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
print(next(gen))
# print(next(gen))    # StopIteration

# 2. 列表生成式
list1 = list(x for x in range(5))
print(list1)

list2 = [x for x in 'abc']
print(list2)

gen2 = (x*10 for x in range(5))
list2 = list(gen2)
print(list2)
# print(next(gen2))   # StopIteration

def yt_list(seq):
    temp = []
    for item in seq:
        temp.append(item)
    return temp


# 3.字典生成式
dict1 = dict((x, x*2) for x in range(5))
print(dict1)   # {0: 0, 1: 2, 2: 4, 3: 6, 4: 8}

"""
2) 語法二:
生成器 = (表達(dá)式 for 變量 in 序列 if 條件語句)

a.展開成函數(shù)
def 函數(shù)名():
    for 變量 in 序列:
        if 條件語句:
            yield 表達(dá)式
生成器 = 函數(shù)名()
"""
gen3 = (x for x in range(10) if x % 2)

"""
def func():
    for x in range(10):
        if x % 2:
            yield x
gen3 = func()
"""
print(list(gen3))


# 補充: python中的三目運算符
"""
C、java、js等中的三目運算符: 變量 = 條件語句?表達(dá)式1:表達(dá)式2
python中的三目運算符: 變量 = 表達(dá)式1 if 條件語句 else 表達(dá)式2

三目運算符的功能: 判斷條件語句是否為True, 如果是結(jié)果是表達(dá)式,否則結(jié)果是表達(dá)式2
"""
a = 19
# num = None
# if a & 1:
#     num = '奇數(shù)'
# else:
#     num = '偶數(shù)'
num = '奇數(shù)' if a & 1 else '偶數(shù)'
print(num)


# 練習(xí): 使用生成式寫一個生產(chǎn)器,能夠產(chǎn)生1~10中所有的數(shù)能否被3整除的結(jié)果
# 1 -> False  2 - > False  3 -> True  4 -> False, ...

gen4 = (True if num % 3 == 0 else False for num in range(1, 11))
print(list(gen4))  # [False, False, True, False, False, True, False, False, True, False]
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 函數(shù) review 1.概念: 對實現(xiàn)特定功能的代碼的封裝2.函數(shù)的聲明def 函數(shù)名(形參列表):函數(shù)說明文檔函...
    漫磋嗟閱讀 283評論 0 0
  • 一、函數(shù)基礎(chǔ) 1. 匿名函數(shù) 匿名函數(shù)就是沒有函數(shù)名的函數(shù) 匿名函數(shù)可以看作類型為function的值,與10,'...
    Lis_reak閱讀 197評論 0 0
  • 你不知道JS:異步 第四章:生成器(Generators) 在第二章,我們明確了采用回調(diào)表示異步流的兩個關(guān)鍵缺點:...
    purple_force閱讀 1,044評論 0 2
  • 函數(shù) 一.匿名函數(shù) 1.匿名函數(shù)匿名函數(shù)就是沒有函數(shù)名的函數(shù);匿名函數(shù)可以看成是類型是function的值。注意:...
    風(fēng)中逐月fzzy閱讀 129評論 0 0
  • 你看看,張大虎又領(lǐng)回來一個媳婦兒。 咋的?人家那是能耐!現(xiàn)在這個社會,好小伙兒都說不上媳婦兒,你再看看人家,都已年...
    半盞流年02閱讀 846評論 0 0

友情鏈接更多精彩內(nèi)容