天天看點

Python【基礎第四篇】

一、疊代器(iterator)

疊代器是通路集合元素的一種方式。疊代器對象從集合的第一個元素開始通路,直到所有的元素被通路完結束。疊代器隻能往前不會後退,不過這也沒什麼,因為人們很少在疊代途中往後退。另外,疊代器的一大優點是不要求事先準備好整個疊代過程中所有的元素。疊代器僅僅在疊代到某個元素時才計算該元素,而在這之前或之後,元素可以不存在或者被銷毀。這個特點使得它特别适合用于周遊一些巨大的或是無限的集合,比如幾個G的檔案

特點:

  • 通路者不需要關心疊代器内部的結構,僅需通過next()方法不斷去取下一個内容
  • 不能随機通路集合中的某個值 ,隻能從頭到尾依次通路
  • 通路到一半時不能往回退
  • 便于循環比較大的資料集合,節省記憶體
#iter()

s = '民主在哪裡'   #s是一個iterable對象,它有__getitem__()方法

it = iter(s)             #it是一個iterator對象,它有 __next__()和__iter__()方法

print(s)
print(it.__next__())
print(it.__next__())
print(it.__next__())
print(it.__next__())
輸出結果:
民主在哪裡
民
主
在
哪                

生成器(generator)

定義:一個函數調用時傳回一個疊代器,那這個函數就叫做生成器(generator),如果函數中包含yield文法,那這個函數就會變成生成器

def cash_money(a):

    while a >0:

        a -= 100

        yield '取走100'                   

        print('又來拿錢了!')

atm = cash_money(500)

print(atm.__next__())

print('我是敗家子,全部花掉')

print(atm.__next__())

print('花掉一分不剩')

print(atm.__next__())
                
  • 作用:

這個yield的主要效果呢,就是可以使函數中斷,并儲存中斷狀态,中斷後,代碼可以繼續往下執行,過一段時間還可以再重新調用這個函數,從上次yield的下一句開始執行。

另外,還可通過yield實作在單線程的情況下實作并發運算的效果

import time

def consumer(name):

    print("%s 準備吃包子啦!" %name)

    while True:

       baozi = yield

 

       print("包子[%s]來了,被[%s]吃了!" %(baozi,name))

 

def producer(name):

    c = consumer('A')

    c2 = consumer('B')

    c.__next__()

    c2.__next__()

    print("老子開始準備做包子啦!")

    for i in range(3):

        time.sleep(1)

        print("做了2個包子!")

        c.send(i)                              #send方法是傳送yield值

        c2.send(i)                          

 

producer('xigang')
                

二、裝飾器

def login(func):

    def inner(arg):

        print('驗證')

        return func(arg)

    return inner

@login                                                        #相當于: tv = login(tv)

def tv(arg1):

    print('welcom to tv page')

 

def movie():

    print('movie')

 

movie()

tv(1)
                

結果:

結果:

movie
驗證
welcom to tv page
                

帶參數裝飾器

#!/usr/bin/env/ python



def Before(request,kargs):

    print('before')



def After(request,kargs):

    print('after')



def Filter(before_func,after_func):

    def outer(main_func):

        def wrapper(request,kargs):

            before_result = before_func(request,kargs)

            if(before_result != None):

                return before_result

            main_result = main_func(request,kargs)

            if(main_result != None):

                return main_result

            after_result = after_func(request,kargs)

            if(after_result != None):

                return after_result

        return wrapper

    return outer



@Filter(Before, After)

def Index(request,kargs):

    print('index')



Index(1,2)
                

三、遞歸

特點

遞歸算法是一種直接或者間接地調用自身算法的過程。在計算機編寫程式中,遞歸算法對解決一大類問題是十分有效的,它往往使算法的描述簡潔而且易于了解。

遞歸算法解決問題的特點:

  • 遞歸就是在過程或函數裡調用自身。
  • 在使用遞歸政策時,必須有一個明确的遞歸結束條件,稱為遞歸出口。
  • 遞歸算法解題通常顯得很簡潔,但遞歸算法解題的運作效率較低。是以一般不提倡用遞歸算法設計程式。
  • 在遞歸調用的過程當中系統為每一層的傳回點、局部量等開辟了棧來存儲。遞歸次數過多容易造成棧溢出等。是以一般不提倡用遞歸算法設計程式。

 要求

遞歸算法所展現的“重複”一般有三個要求:

  • 一是每次調用在規模上都有所縮小(通常是減半);
  • 二是相鄰兩次重複之間有緊密的聯系,前一次要為後一次做準備(通常前一次的輸出就作為後一次的輸入);
  • 三是在問題的規模極小時必須用直接給出解答而不再進行遞歸調用,因而每次遞歸調用都是有條件的(以規模未達到直接解答的大小為條件),無條件遞歸調用将會成為死循環而不能正常結束。

當在上千萬元素清單中查找一個元素,周遊清單會非常慢,一個一個周遊尋找,用遞歸方法可以迅速找到,如下:

def binary_search(data_source,find_n):

    mid = int(len(data_source)/2)

    if len(data_source)>1:

        if data_source[mid] >find_n:

            print('data in left of %s' % data_source[mid])

            binary_search(data_source[:mid],find_n)

        elif data_source[mid] <find_n:

            print('data in right of %s' % data_source[mid])

            binary_search(data_source[mid:],find_n)

        else:

            print('found find_s,',data_source[mid])

    else:

        print('cannot find ........')

 

if __name__ == '__main__':

    data = list(range(1,7000000))

    binary_search(data,655350)                

四、算法

要求:生成一個4*4的2維數組并将其順時針旋轉90度

array=[[col for col in range(5)] for row in range(5)] #初始化一個4*4數組

#array=[[col for col in 'abcde'] for row in range(5)]

  

for row in array: #旋轉前先看看數組長啥樣

    print(row)

  

print('-------------')

for i,row in enumerate(array):

  

    for index in range(i,len(row)):

        tmp = array[index][i] #get each rows' data by column's index

        array[index][i] = array[i][index] #

        print tmp,array[i][index]  #= tmp

        array[i][index] = tmp

    for r in array:print r

  

    print('--one big loop --')
                

五、正規表達式

比對格式

模式 描述

^ 比對字元串的開頭

$ 比對字元串的末尾。

. 比對任意字元,除了換行符,當re.DOTALL标記被指定時,則可以比對包括換行符的任意字元。

[...] 用來表示一組字元,單獨列出:[amk] 比對 'a','m'或'k'

[^...] 不在[]中的字元:[^abc] 比對除了a,b,c之外的字元。

re* 比對0個或多個的表達式。

re+ 比對1個或多個的表達式。

re? 比對0個或1個由前面的正規表達式定義的片段,非貪婪方式

re{ n}

re{ n,} 精确比對n個前面表達式。

re{ n, m} 比對 n 到 m 次由前面的正規表達式定義的片段,貪婪方式

a| b 比對a或b

(re) G比對括号内的表達式,也表示一個組

(?imx) 正規表達式包含三種可選标志:i, m, 或 x 。隻影響括号中的區域。

(?-imx) 正規表達式關閉 i, m, 或 x 可選标志。隻影響括号中的區域。

(?: re) 類似 (...), 但是不表示一個組

(?imx: re) 在括号中使用i, m, 或 x 可選标志

(?-imx: re) 在括号中不使用i, m, 或 x 可選标志

(?#...) 注釋.

(?= re) 前向肯定界定符。如果所含正規表達式,以 ... 表示,在目前位置成功比對時成功,否則失敗。但一旦所含表達式已經嘗試,比對引擎根本沒有提高;模式的剩餘部分還要嘗試界定符的右邊。

(?! re) 前向否定界定符。與肯定界定符相反;當所含表達式不能在字元串目前位置比對時成功

(?> re) 比對的獨立模式,省去回溯。

\w 比對字母數字

\W 比對非字母數字

\s 比對任意空白字元,等價于 [\t\n\r\f].

\S 比對任意非空字元

\d 比對任意數字,等價于 [0-9].

\D 比對任意非數字

\A 比對字元串開始

\Z 比對字元串結束,如果是存在換行,隻比對到換行前的結束字元串。c

\z 比對字元串結束

\G 比對最後比對完成的位置。

\b 比對一個單詞邊界,也就是指單詞和空格間的位置。例如, 'er\b' 可以比對"never" 中的 'er',但不能比對 "verb" 中的 'er'。

\B 比對非單詞邊界。'er\B' 能比對 "verb" 中的 'er',但不能比對 "never" 中的 'er'。

\n, \t, 等. 比對一個換行符。比對一個制表符。等

\1...\9 比對第n個分組的子表達式。

\10 比對第n個分組的子表達式,如果它經比對。否則指的是八進制字元碼的表達式。

正規表達式常用5種操作

  • 1、re.match(pattern, string)     # 從頭比對
  • 2、re.search(pattern, string)    # 比對整個字元串,直到找到一個比對
  • 3、re.split()            # 将比對到的格式當做分割點對字元串分割成清單
>>>m = re.split("[0-9]", "alex1rain2jack3helen rachel8")

>>>print(m)

輸出: ['alex', 'rain', 'jack', 'helen rachel', '']
                
  • 4、re.findall()          # 找到所有要比對的字元并傳回清單格式
>>>m = re.findall("[0-9]", "alex1rain2jack3helen rachel8")

>>>print(m)<br>

輸出:['1', '2', '3', '8']
                
  • 5、re.sub(pattern, repl, string, count,flag)    # 替換比對到的字元
m=re.sub("[0-9]","|", "alex1rain2jack3helen rachel8",count=2 )

print(m)

輸出:alex|rain|jack3helen rachel8
                
  • re.match與re.search的差別

re.match隻比對字元串的開始,如果字元串開始不符合正規表達式,則比對失敗,函數傳回None;而re.search比對整個字元串,直到找到一個比對。

轉載于:https://www.cnblogs.com/microfan/p/5196993.html