python系列4

巴扎黑
發布: 2017-06-23 16:29:47
原創
1574 人瀏覽過

目錄

  • 遞迴演算法解析

  • 冒泡排序解析

  • 裝飾程式解析

#1遞歸

  1. 遞歸的定義
    遞歸(Recursion),又成為遞回,在數學與計算機科學中,是指在函數的定義中使用函數自身的方法。遞歸一詞也較長地用於描述以自相似方法重複事物的過程。

F0 = 0F1 = 1
登入後複製

  2. 遞歸的原理

    (1). 範例:

 defth == 5= a1 += defth + 1== recursion(1, 0, 1(ret)
登入後複製

 

  以下這幅圖為整個函數的執行過程,紅色的代表一層一層的往裡面嵌套,綠色的代表函數的返回值一層一層的外面返還。其實遞歸就是這個原理,透過一個函數的執行流在再次進入此函數,當通過一個條件返回一個值之後,一層一層的按照剛剛的執行流再次返回回去,最後得到返回值,但是遞歸的時候要注意兩點:

  1. 他的條件,必須要使他的遞歸在某個條件內可以返回一個值,否則就會一直遞歸,直到電腦資源耗盡(Python預設有遞歸的次數限制)

  2. 傳回值,在裡面的遞歸函數一般要給他一定的回傳值,否則在最後一次返還遞歸的時候會得不到想要的值。

   

二. 冒泡排序

  1. 冒泡排序原理

    冒泡排序就是一種簡單的排序演算法。他重複的走訪過要排序的數列,一次比較兩個元素,如果他們的順序錯誤就把他們交換過來。

冒泡排序算法的运作如下:
  1. 比较相邻的元素。如果第一个比第二个大,就交换他们两个。
  2. 对每一对相邻元素作同样的工作,从开始第一对到结尾的最后一对。这步做完后,最后的元素会是最大的数。
  3. 针对所有的元素重复以上的步骤,除了最后一个。
  4. 持续每次对越来越少的元素重复上面的步骤,直到没有任何一对数字需要比较
登入後複製
###    交換資料的原理 ######    借助一個外圍的變數先保存原來的值,然後再去透過指向位址的轉換來進行交換資料。注意:當temp指向了a, 然後a再指向b的時候,temp本身的指向是沒有發生改變的,就如下圖,a指向了b,但是temp依然指向的是a的地址,所以他還是66# #####
a = 66b = 88temp = a 
a = b 
b = temp
登入後複製
######  #########    冒泡排序的原理######  ######### ######」泡排序範例######
 1 # -*- coding:utf-8 -*- 2 # zhou 3 # 2017/6/17 4 list = [0, 88, 99, 33, 22, 11, 1] 5 for j in range(1, len(list)): 6     for i in range(len(list) - j): 7         # 如果第一个数据大, 则交换数据, 否则, 不做改变 8         if list[i] > list[i + 1]: 9             temp = list[i]10             list[i] = list[i + 1]11             list[i + 1] = temp12 print(list)
登入後複製
######三. 裝飾器######  1. 裝飾器定義######     裝飾器是什麼?簡單來說就是在不改變原始函數程式碼的基礎上,對程式碼的一種微妙的擴展,以使得其功能進一步增強的函數。裝飾器就是一個函數,一個載入在其他函數之上的函數,######    以下我們先來了解幾個概念:######    <1>. 函數執行流##### #      由以上面的可知,函數的執行流應該是從上到下的,也就是說,程式碼先把第一個test1載入到記憶體中,然後從新開闢一塊記憶體來存放第二個test1。 ######      這裡應該是第一個test1的指向改到了890673481792這裡。 ######
def test1():print('日本人.')print(id(test1))def test1():print('中国人.')print(id(test1))
test1()

执行结果:890673481656
890673481792中国人.
登入後複製
######    <2>.  函數作為變數######      由以下結果可以看出來,函數名其實就是一個變數,可以用來傳遞的變數。 ############      注意:函數作為變數的時候不能加括號,必須只是函數名稱############
(=<function test1 at 0x000000E2D403C7B8>
<function test1 at 0x000000E2D403C7B8>
登入後複製
######    .  函數巢狀######      這裡定義了三個函數,test1,test2,test3, 3裡面嵌套了1, 1裡面又嵌套了2,從他的結果中想必你也會看出來函數的執行流。 ######
def test1():print('我是',end='')def test2():print('中国人.')
    test2()def test3():
    test1()print('Hello, China.')
test3()

结果:
我是中国人.
Hello, China.
登入後複製
###

  2. 装饰器原理

    (1). 装饰器的写法和使用

      <1>. 装饰器也是一个函数

      <2>. 使用装饰器的格式: 在一个函数前面加上:@装饰器的名字

    (2). 装饰器的原理

      <1>. 把test1函数当做一个变量传入outer中

          func = test1

      <2>. 把装饰器嵌套的一个函数inner赋值给test1

          test1 = inner

      <3>. 当执行test1函数的时候,就等于执行了inner函数,因此在最后的那个test1()命令其实执行的就是inner,因此先输出(你是哪国人)

      <4>. 按照执行流执行到func函数的时候,其实执行的就是原来的test1函数,因此接着输出(我是中国人),并把它的返回值返回给了ret

      <5>. 当原来的test1函数执行完了之后,继续执行inner里面的命令,因此输出了(Oh,hh, I love China.)

    (3). 装饰器的总结

      由上面的执行流可以看出来,其实装饰器把之前的函数当做参数传递进去,然后创建了另一个函数用来在原来的函数之前或者之后加上所需要的功能。

(=((
登入後複製

 

  3. 带参数的装饰器

    为了装饰器的高可用,一般都会采用下面的方式,也就是无论所用的函数是多少个参数,这个装饰器都可以使用

    Python内部会自动的分配他的参数。

# -*- coding:utf-8 -*-# zhou# 2017/6/17def outer(func):def inner(a, *args, **kwargs):print('你是哪国人?')
        ret = func(a, *args, **kwargs)print('Oh, hh, I love China.')return inner

@outerdef test1(a, *args, **kwargs):print('我是中国人.')

test1(1)
登入後複製

  3.  装饰器的嵌套

   <1>. 第一层装饰器的简化(outer装饰器)

    

    

    <2>. 第二层装饰器简化(outer0装饰器)

    

    <3>. 装饰器嵌套攻击额,我们可以发现一层装饰器其实就是把原函数嵌套进另一个函数中间,因此我们只需要一层一层的剥开嵌套就可以了。

# -*- coding:utf-8 -*-# zhou# 2017/6/17def outer0(func):def inner():print('Hello, Kitty.')
        ret = func()print('我是日本人.')return innerdef outer(func):def inner():print('你是哪国人?')
        ret = func()print('你呢?')return inner
@outer0
@outerdef test1():print('我是中国人.')

test1()

结果Hello, Kitty.
你是哪国人?
我是中国人.
你呢?
我是日本人.
登入後複製

 

 

  

 

以上是python系列4的詳細內容。更多資訊請關注PHP中文網其他相關文章!

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!