python應用(5):變量類型與數據結構

如前所說,寫程序如同給算法寫殼,而算法就是流程,因此流程是程序的主角(但這個流程不必定要你來設計)。在程序中,爲了配合流程(算法)的實現,除了順序、分支與循環語句的使用,還要藉助「變量」這個角色。變量是重要的角色,男二號。python

變量表示可變化的值,但這個值是有範圍的,並非全部值均可以放置到同一個變量中,值的範圍,由變量的類型決定。git

變量的類型,決定兩個事情,一是用多大的空間來存儲這個變量值,二是這個變量值的範圍是多少。好了,這個不重要,先不要管這個細節,先把變量用起來,並掌握一些基礎知識便可。算法

變量有哪些類型呢?數據結構

(1)數字類型、bool與字符串

這三個是常見的內置類型。app

注意,值,決定了變量的類型,你給變量賦什麼值,它就是什麼類型。好比:函數

a = 10 # int整數類型
a = 9.9 # float浮點類型。變量名仍是a,可是值的變化,讓它變成了一個新的變量
a = 987654321L # long長整數類型,值以'L'結束
a = 3+4j # complex複數類型

以上幾個變量類型,分別是int、float、long跟complex類型,這幾個類型能夠歸爲數字類型。post

除了數字類型,python中的值還有bool類型跟str字符串類型,好比:this

a = False # bool類型,值要麼爲False,要麼爲True
a = "hellotype" # str字符串類型

若是想知道當前變量是什麼類型,那可使用內置函數(python提供的一組函數)type()來確認,好比能夠這樣,留意type()的輸出:
python的變量類型spa

因此,基本上,python的變量類型,包括數字類型(int/float/long/complex)、bool跟str。設計

其中,str,即字符串,對它的操做會常常遇到,好比:

a = "hellotype"
a[1:] # 第1個字符到最後(注意索引是從0開始的)
a[2:]
a = "123456"
a[1:5] # 第1個字符到第5個字符的內容,但不包括第5個字符,也就是左閉右開的區間
a[-1] # -1表示最後一個字符,-2就是倒數第二個,如此類推

執行效果:
字符串訪問示例

(2)常見的數據結構

除了以上常見的內置變量類型,pyton還提供了一些經常使用的數據結構,這些數據結構也是變量類型。

數據結構服務於算法,但因爲某些數據結構實在太經常使用了,以致於不少算法都有它們的身影,因而,把這些經常使用的數據結構抽離出來,作爲一個獨立的結識點來說,也是很合理的,但明顯不是本文的事情。

數據結構,就是數據的組織結構,各個數據結構必定會有本身的組織特色。python中有幾個常見的內置的數據結構,由於常用,甚至已經被看成變量類型,跟數字類型、bool與str同樣的存在。

這幾個常見的數據結構,分別是:列表、元組、集合、字典。

一樣,值決定類型(或數據結構)。

list即列表,也是由值定義出來(以[]來定義),好比:

a = [1,2,3,4] # list
type(a)

list的操做,跟字符串的相似,好比:
list操做

tuple即元組,是隻讀列表(以()來定義),也就是元組的內容不容許修改,好比:

a = ('hellotuple', 123, True)
a[0]
a[1] = 100 # 試圖修改元組的內容,會報錯
a * 2 # 跟list的操做一致,內容重複2次,併產生新的元組
b = (1,2)
a + b # 元組相加是能夠的,由於產生了新的元組,並無修改原來的元組

執行的效果以下:
tuple操做

list跟tuple的特色,是能夠存聽任意類型的元素,內容有序、可重複。

另外一種常見的數據結構是set,特色是,能夠存聽任意類型的元素,內容是無序的,並且不能重複,這個就是集合的特色。

set即集合的部分使用以下(以{}來定義):

a = {2, True, 'helloset'}
a[2] # 集合set是無序,因此沒有索引可言,試圖使用索引會致使報錯
b = set('helloset') # 使用構造函數來建立一個set,注意集合中的元素會去重(這裏元素是字符)
b = {'a', 'a', 1} # 元素會被去重

執行的效果以下:
set操做

最後一種數據結構是dict,也就是字典。

dict也是一個集合,是鍵值對(key-value)的集合,一樣以{}來定義,但包括key跟value,好比:

d = {'k1':1, 'k2':2}

dict跟set相似,內容無序,並且key不能重複。set只保留了key(無序且不重複),而去掉了value。

dict的部分使用以下:

d = {}
d['k1'] = "hellodict"
d[2] = "this is int"
d[True] = "bool true"
a = {'a':'first one', 'd':'hellodict', 3:'three', 'e':34.45}

執行效果以下:
ditc操做

以上四種內置類型之間的轉換,有可能在實際場景中應用到,操做上很簡單,只須要用類型名去處理須要轉換的值便可,好比:

a = list(set1) # type_name(xxx)

以上是list、tuple、set與dict的簡單介紹,你能夠根據實際場景去使用它們。

另外,我並無介紹這四種數據結構的操做函數,實事上,被抽離封裝的數據結構都有一系列操做函數,也就是對象的行爲(對象不是指女友),好比以上幾種數據結構,有對應的append()、pop()、remove()等一系列的操做,這個在實踐中再去理解與運用了。

(3)變量類型使用示例

不論是簡單的變量類型(數字類型等)仍是常見的數據結構(list等),你均可以把它們歸爲變量類型。這些變量類型常常被使用,由於變量是程序的重要配角。

我在這裏舉幾個示例,都是以list做爲棧來解決問題的例子,但願讓你對變量類型有一個使用上的感知,而後在實際場景中靈活使用。

(a)判斷左右符號是否配對

左符號:([{

右符號:)]}

配對的狀況如:'([]){()}',不配對的狀況如:'[{]}]'。

用棧來理解就是:遍歷全部字符。遇左符號則入棧;遇右符號則出棧(若是爲空則直接返回False),出棧返回的字符若是與右符號不配對則返回False,若是配對則繼續下一個字符。全部字符遍歷完後,棧非空則返回False,不然返回True。

def sybol_match(str):
    L=['(','{','['];
    R=[')','}',']'];
    s=[]
    for c in str:
        if c in L:
            s.append(c)
        else:
            if not s:
                return False
            a=s.pop()
            lp = L.index(a)
            rp = R.index(c)
            if lp!=rp:
                return False
    return not s

(b)計算後綴表達式

計算一個表達式時,表達式能夠以中綴或後綴的方式錄入,然後綴表達式因爲不須要使用括號而簡化了處理,因此是一個廣泛的選擇。

好比:

中綴:12 (2/2) 後綴:12 2 2 /
中綴:10-(2 3) 後綴:10 2 3 -
中綴:(3-2) (9/3)+5 後綴:3 2 - 9 3 / 5 +

你能夠畫出樹狀圖,再來理解(好比後綴遍歷獲得後綴表達式)。

用棧來理解就是:遍歷全部分割項(以空格切分)。遇到數字則入棧;遇到操做符出棧兩次(這裏簡化爲都是二元操做,第一次出棧的爲參數2,第二次爲參數1),並進行運算,再把結果入棧。遍歷完全部分割項後,返回棧中內容(只有一個值)。

operators = {
        '+' : lambda p1, p2: p1+p2,
        '-' : lambda p1, p2: p1-p2,
        '*' : lambda p1, p2: p1*p2,
        '/' : lambda p1, p2: p1/p2,
        }
def calc_postfix(str):
    expr = str.split()
    s = []
    for e in expr:
        if e.isdigit():
            s.append(int(e))
        else:
            f = operators[e]
            p2 = s.pop()
            p1 = s.pop()
            s.append(f(p1, p2))

    return s.pop()

(c)揹包問題

有若干個物品,每個物品都有重量。揹包有最大容量限制,求恰好裝滿揹包最大容量的全部解。

好比:

物品名稱 重量
物品0 1kg
物品1 8kg
物品2 4kg
物品3 3kg
物品4 5kg
物品5 2kg
揹包最大能夠裝10kg,那可能的解是:[0,2,3,5]、[1,5]等。

用棧來理解就是:盡情地裝(按物品順序,只要能裝得下就裝),若是剩餘容量恰好爲0或者以後的各個物品都裝不下了,則出棧,即拿掉最後的一個物品k,再繼續從k+1個物品開始裝。在棧爲空並且填裝的物品的索引已經超出範圍,則結束循環。因爲,總會一直出棧到一個物品都沒有,再從下一個物品開始填裝,因此必定會出現棧爲空且沒有物品可裝的狀況。

def knapsack(w, ws):
    """
    w --揹包容量
    ws --物品重量列表 [1, 3, ..]
    """
    ret = []
    s = []
    i = 0
    cnt = len(ws)
    rest = w
    while s or i < cnt:  # 棧不爲空或者還有得裝
        while i < cnt and rest > 0:  # 還有得裝且還有容量
            if rest >= ws[i]:  # 裝得下就裝
                s.append(i)
                rest -= ws[i]
            i += 1   # 無論當前的是否裝得下,都要嘗試下一個
        if rest == 0:
            ret.append(s[:])  # one solution
        i = s.pop()
        rest += ws[i]
        i += 1
    return ret
        
if __name__ == '__main__':
    # print(sybol_match('[{()}]{}[()]()'))
    # print(sybol_match('[({}])'))
    # print(calc_postfix('12 2 2 / *'))
    # print(calc_postfix('3 2 - 9 3 / * 5 +'))
    ret = knapsack(10, [1, 8, 4, 3, 5, 2]) 
    print(ret)

以上是幾個示例,你可沒必要關心算法的設計,由於這是另外的話題,重點關心代碼中變量類型的使用,好比list、dict的使用等。


好了,本文介紹了python的變量類型跟常見的數據結構,你能夠把內置的數據結構也看成變量類型。變量類型包括int、float、long、complex、bool、list、tuple、set、dict。文章最後還就list舉了幾個使用例子,但願能夠幫助你理解變量類型的使用。有緣再見,see you。

相關文章
相關標籤/搜索