Python入門-高級數據結構

< 返回索引頁html

高級數據結構

咱們知道Python的變量數據類型有整型、浮點型、複數、字符串和布爾型,咱們會發現這些類型結構都比較的簡單。在咱們學習數學時,有整數、浮點數等這些基本的數據類型,還有數組等這種高級的數據類型供咱們來處理一些複雜的數據問題使用。那麼Python語言做爲一門高級的編程語言,對這些高級的數據結構也是支持的。segmentfault

下面讓咱們一塊來看下Python的中高級數據結構。數組

列表與元組

什麼是列表

列表,Python 類爲list,一種Python的高級數據結構,使用中括號包含,其中內部元素使用逗號分隔,內部元素能夠是任何類型包含空。有點像咱們數學中學習的數組。數據結構

a = [1,2,3]
b = ['1',2,None]
c = [1,2,[3,4]]
d = []
e = [1]

知識點:app

  • 列表中的元素是有序的。

列表的操做

列表的下標操做ssh

  • 獲取列表中的值

列表和字符串同樣是能夠經過下標來獲取指定位置的元素的。列表的下標是從1開始的,最大下標值爲元素個數減1或-1表示。

>>> a = [1,2,3]
>>> print(a[1])
2
  • 列表更新

可經過列表的下標來替換更新列表中指定元素。

>>> a = [1,2,3]
>>> a[2] = '2'
>>> a
[1, 2, '2']
>>>
  • 列表的刪除
>>> a
[1, 2, '2']
>>> del a[2]
>>> a
[1, 2]
  • 切片

可經過下標來作列表的截取等操做,在Python中也叫切片。格式如:list[start_index:end_index:step_length]
start_index開始下標省略時,默認爲 0 ;end_index結束下標省略時,默認爲最大下標,及長度-1-1step_length步長省略時,默認爲1。

>>> a
[1, 2, 3, 4]
>>> a[1:-1]
[2, 3]
>>> t = [1,2,3,4,5]
>>> t[::2]
[1, 3, 5]

運算符及內建函數操做

  • 可用使用內建函數len 來獲取列表的長度,該長度及列表元素的個數。
>>> a
[1, 2]
>>> len(a)
2
>>> a[::2]
[1, 3]
  • 列表可以使用運算符 +實現鏈接操做。
>>> [1,2,3]+[5,6,7]
[1, 2, 3, 5, 6, 7]
  • 可使用內建函數reversed 將列表反轉,該函數返回一個迭代器(可理解爲一個可遍歷對象便可,後邊會講解)。
>>> a = [1,2,3,4]
>>> reversed(a)
<list_reverseiterator object at 0x10634ee10>  
>>> list(reversed(a))
[4, 3, 2, 1]

除了使用reversed 函數,也可以使用列表的切片來反轉:

>>> a
[1, 2, 3, 4]
>>> a[::-1]
[4, 3, 2, 1]
  • python 可以使用 * 來實現重複。
>>> [1]*2
[1, 1]
  • 列表也支持innot in成員運算符
>>> 3 in [1,2,3]
True
>>> 3 not in [1,2,3]
False

列表的方法

>>> dir(list)
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
  • list.append(obj) 在列表末尾添加新的對象
  • list.count(obj) 統計某個元素在列表中出現的次數
  • list.extend(seq) 在列表末尾一次性追加另外一個序列中的多個值(用新列表擴展原來的列表)
  • list.index(obj) 從列表中找出某個值第一個匹配項的索引位置
  • list.insert(index, obj) 將對象插入列表
  • list.pop([index=-1]]) 移除列表中的一個元素(默認最後一個元素),而且返回該元素的值
  • list.remove(obj) 移除列表中某個值的第一個匹配項
  • list.reverse() 反向列表中元素
  • list.sort(cmp=None, key=None, reverse=False) 對原列表進行排序
  • list.clear() 清空列表
  • list.copy() 複製列表

什麼是元組

元組,Python中類爲 tuple。使用小括號包括,內部元素使用逗號分隔,可爲任意值。與列表不一樣之處爲,其內部元素不可修改,及不能作刪除、更新操做。

>>> a = (1,2,3)
>>> b = ('1',[2,3])
>>> c = ('1','2',(3,4))
>>> d = ()
>>> e = (1,)

說明:

  • 當元組中元素只有一個時,結尾要加逗號。若不加逗號,python解釋器將解釋成元素自己的類型,而非元組類型。

元組的操做

經過下標操做

  • 經過小標來獲取元素值,使用方法同列表。
  • 切片的處理,使用方法同列表。
  • 不可經過下標作刪除和更新操做。
>>> c[0] = 1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> del c[0]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'tuple' object doesn't support item deletion

運算符及內建函數操做

  • 元組自己是不可變,可是可經過+來構成新的元組。
>>> a
(1, 2, 3)
>>> b
('1', [2, 3])
>>> a + b
(1, 2, 3, '1', [2, 3])
  • 可以使用內建函數 len 獲取元組長度。
  • 可以使用* 元素符實現元素的重複。
>>> a
(1, 2, 3)
>>> a*2
(1, 2, 3, 1, 2, 3)
  • 元組也支持innot in 成員運算符。

字典與集合

字典的定義

在編程世界中,有一種高級結構是使用比較普遍的,即key和value值一一對應的映射結構。它就像一個字典同樣,經過關鍵字key,來找到對應的value值。該種結構在Python中叫作字典,英文爲dict,使用大括號包括,其中元素爲冒號分隔key-value對,中間用逗號分隔。

結構以下:

>>> a = {'name':'Tim', 'age':18}
>>> b = {}
>>> c = dict(name='Tim', age=18)
>>> d = {(1,2):'Time'}

知識點:

  • 字典中,key 值惟一,且類型爲不可變類型,如字符串、元組、數字。
  • value 值能夠爲任意類型;
  • 字典中的元素是無序的。

字典的操做

獲取字典某元素

可以使用key和方法get來獲取字典中的值。

>>> a = {'name':'Tim', 'age':18}
>>> a['name']
'Tim'
>>> a.get('name','')
'Tim'
>>> a['address']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: 'address'

知識點:

  • 當字典沒有沒有該key時,使用key獲取,會拋出KeyError錯誤;使用get不會拋出,會返回None。
  • 可以使用get(key,[default])函數給

更新和刪除字典

字典是可變的,可經過key來作更新和刪除操做。

# 修改 
>>> a
{'name': 'Tim', 'age': 18}
>>> a['address'] = 'Beijing'
>>> a
{'name': 'Tim', 'age': 18, 'address': 'Beijing'}
# 刪除
>>> del a['age']
>>> a
{'name': 'Tim', 'address': 'Beijing'}

字典的方法操做

字典的方法提供了更加豐富的操做功能:

  • radiansdict.clear() 刪除字典內全部元素
  • radiansdict.copy() 返回一個字典的淺複製,返回原字典的引用
  • radiansdict.fromkeys() 建立一個新字典,以序列seq中元素作字典的鍵,val爲字典全部鍵對應的初始值
  • radiansdict.get(key, default=None) 返回指定鍵的值,若是值不在字典中返回default值
  • key in dict 若是鍵在字典dict裏返回true,不然返回false
  • radiansdict.items() 以列表返回可遍歷的(鍵, 值) 元組數組
  • radiansdict.keys() 以列表返回一個字典全部的鍵
  • radiansdict.setdefault(key, default=None) 和get()相似, 但若是鍵不存在於字典中,將會添加鍵並將值設爲default
  • radiansdict.update(dict2) 把字典dict2的鍵/值對更新到dict裏
  • radiansdict.values() 以列表返回字典中的全部值
  • pop(key[,default]) 刪除字典給定鍵 key 所對應的值,返回值爲被刪除的值。key值必須給出。 不然,返回default值。
  • popitem() 隨機返回並刪除字典中的一對鍵和值(通常刪除末尾對)。

集合的定義

集合(set)和字典(dict)相似,它是一組 key 的集合,但不存儲 value。集合的特性就是:key 不能重複。

>>> s = {'1','2','3'}  # 不推薦,當元素中有字典時,會報錯
>>> s
{'2', '1', '3'}
>>> s2 = set(['1','2','3'])
>>> s2
{'2', '1', '3'}
>>> type(s)
<class 'set'>
>>> type(s2)
<class 'set'>

集合的操做

交集、並集和合集

Python中的集合與數學中的集合同樣,也有交集、並集和合集。

>>> s1 = {1,2,3,4,5}
>>> s2 = {1,2,3}
>>> s3 = {4,5}
>>> s1&s2   # 交集
{1, 2, 3}
>>> s1|s2   # 並集
{1, 2, 3, 4, 5}  
>>> s1 - s2  # 差差集
{4, 5}
>>> s3.issubset(s1)   # s3 是否爲s1 的子集
True
>>> s1.issuperset(s2)  # s1 是否爲 s2 的超集
True

集合的方法操做

集合中經常使用方法以下:

  • set.add(obj) 添加集合元素
  • set.remove(obj) 刪除集合元素
  • set.update(set) 合併集合
  • set.pop() 隨機刪除一個元素,並返回該元素

序列

序列(sequence),在Python中是一種具備相同特性的高級數據結構的統稱,可使用下標來獲取元素和切分。到如今,咱們學習了列表、元組、字典和集合4種高級數據結構。能夠發現,列表和元組在操做上有許多相同的地方。除了列表和元組,還有字符串也是序列。可見列表、元組、字符串爲序列,字典、集合、數值爲非序列。

序列的通用操做

  • 經過索引來獲取元素值
  • 分片操做
  • 經過+合併元素
  • 經過*來複制元素
  • 支持成員運算符
  • 最大值、最小值和長度函數支持
>>> l = [1,2,3]
>>> t = (1,2,3)
>>> s = '123'
>>> print(l[0],t[1],s[2])
1 2 3
>>> print(l[:1],t[:2],s[:-1])
[1] (1, 2) 12
>>> print(l+[4], t+(4,), s+'4' )
[1, 2, 3, 4] (1, 2, 3, 4) 1234
>>> print(l*2, t*2, s*2)
[1, 2, 3, 1, 2, 3] (1, 2, 3, 1, 2, 3) 123123
>>> print(2 in l, 2 in t, '2' in s)
True True True
>>> print(max(l), min(t), len(s))
3 1 3

可變類型和不可變類型

除了序列,Python中還能夠根據數據結構內存中的數值是否能夠被改變,分爲可變類型不可變類型

這裏的可變不可變,是指內存中的值是否能夠被改變。若是是不可變類型,在對對象自己操做的時候,必須在內存中新申請一塊區域(由於老區域#不可變#)。若是是可變類型,對對象操做的時候,不須要再在其餘地方申請內存,只須要在此對象後面連續申請(+/-)便可,也就是它的地址會保持不變,但區域會變長或者變短。

  • 可變類型(mutable):列表,字典,集合;
  • 不可變類型(unmutable):數字,字符串,元組;

深copy和淺copy

在學習字典時,字典有個copy,能夠獲得字典的副本。其餘類型如何處理呢,Python提供了一個內置的copy庫用來支持其餘類型的複製。copy庫主要有2個方法,copydeepcopy分別表示淺拷貝和深拷貝。淺拷貝是新建立了一個跟原對象同樣的類型,可是其內容是對原對象元素的引用。這個拷貝的對象自己是新的,但內容不是。拷貝序列類型對象(列表元組)時,默認是淺拷貝。

下面我們來分析下淺拷貝和深拷貝的區別。

普通狀況下,賦值只是建立一個變量,該變量指向值內存地址,以下例:

n4 = n3 = n2 = n1 = "123/'Wu'"

n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n2 = n1

淺拷貝,在內存中只額外建立第一層數據,以下圖:

import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n3 = copy.copy(n1)

深拷貝,在內存中將全部的數據從新建立一份(排除最後一層,即:python內部對字符串和數字的優化),以下圖:

import copy
n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
n4 = copy.deepcopy(n1)

圖片來源:博客地址

總結

到此,咱們把Python的基本語法和數據結構過了一遍。那咱們來總結下,咱們都學到了什麼:

  • 一、高級數據結構及其操做:列表、元組、字典、集合、序列;

這些只是基本語法的組成元素。在程序運行時,可能會有多種狀況,須要對這些結構作判斷或者須要按順序讀取列表的所有元素,那麼這個時候便須要邏輯處理結構。下一章,咱們來說解Python中的邏輯處理的控制流語法。

練習

  • 一、如今有一個包含N個元素的元組或者是序列,怎樣將它裏面的值解壓後同時賦值給N個變量?
>>> data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]
>>> name, shares, price, date = data
>>> data = [ 'ACME', 50, 91.1, (2012, 12, 21) ]
>>> _, shares, price, _ = data
  • 二、怎樣從一個集合中得到最大或者最小的N個元素列表?
max([1,2,2,3])
min([1,2,3,4])
  • 三、你們知道字典是無序的,如何給字典排序?
from collections import OrderedDict

d = OrderedDict()
d['foo'] = 1
d['bar'] = 2
d['spam'] = 3
d['grok'] = 4
print(d)

參考

相關文章
相關標籤/搜索