Python3組合資料型別(元組、列表、集合、字典)語法

覆手為雲p發表於2017-05-25

 

一、序列型別(字串,元組(),列表[])

 

序列型別支援in,len(),分片[],迭代,5種內建序列型別:bytearray,bytes,list,str,tuple(元組)。

1、元組可以巢狀(如:x=str[2][1][0][1])

2、元組的命名(collections.namedtuple(),即自定義)

       樣:sale=collctions.namedtuple("sale","productid customerid date price") 逗號前的為元組型別的名稱,逗號後的引數為字串,用空格分隔,每個名稱都代表該元組資料型別的一項,資料項如:x=sale(121,"2017-03-22",1,10.99);呼叫某一項則可用x.price來實現,此處結果為10.99;

       對於格式化替換,可用**namedtuple._asdict()函式實現直接用名稱替換索引,如:"{productid}{price}".format(**x._asdict())。此方法用於多層元組較好,name即為最外層元組的name.

       單個元素的元組需要加上逗號。

3、列表

       1>列表也可儲存任意型別的資料,且可使用比較操作符(逐項進行比較)和修改列表內容。

       2>列表支援元組的所有操作,同時還有以下函式:

       append()  追加

       count(x)  統計x出現的次數

       index(x,start,end)找x,如沒有則產生一個ValueError,

       extend()    (等同於+=),

       insert(i,x)  (在索引位置i處插入x),

       pop()    移除最後一項

       pop(i)    (移除i索引位置處的資料項,如沒有i值,則預設移除最後一項),

       remove(x)  (移除從左邊開始出現的第一個資料為x的項,如沒有則返回一個ValueError),

       reverse()    反轉,

       sort()     排序。

       對序列特定位置進行賦值可以對列表中單個資料進行替換修改(x[1]=2;x[1:2]=[a,b],對片進行替換時新資料項的個數不一定要等於原資料項的個數,可以是任意個數,結果都是新的分片替換已選定的分片,如果新的替換分片為空,就相當於刪除了已選定的原分片),del x[1:2]也可以起到刪除這一分片的效果(不過del其實是解除了這一資料項與變數之間的繫結)。

       3>用*對序列進行拆分賦值

       樣:a,*b,c=[1,2,3,4,5,6]  -> a,b,c=(1, [2, 3, 4, 5], 6)

       資料項按位置依次經變數賦值,然後將剩餘的所有資料都賦給帶有*號的變數。*的作用就是將一個iterable進行拆分.

       “*”的另一個作用是複製操作符,其效果相當於乘號,不過物件不限於數字,可以為任何物件。

       4>列表內涵(用於建立一些含有大量資料的列表)

       [expression for item in iterable](對iterable中每個資料項進行expression操作)

       [expression for item in iterable if condition],對限定條件的物件進行操作。

       例:leaps=[y for y in range(1900,2000) if (y%4==0 and y%100!=0)or(y%400==0)] 計算閏年。(range同樣為前閉後開)

       列表內涵的多變數巢狀:

       例:cods=[s+z+c for s in "MF" for z in "SMLX" for c in "BGW"

              if not(s=="F" and z=="X")]相當於三層疊加的for迴圈.

 

二、集合型別(set)({})

 

  set支援 in ,len(),比較,位邏輯操作符;並且也是iterable的。只有可hash運算的物件才可以新增到集合中。所有內建的固定資料型別(float,frozenset,int,str,tupul...)都是可hash運算的。內建的可變資料型別(如:dict,list,set)都不是可hash運算的。

  建立一個集合可用set("a","b",3),且建立一個空集合必須用set()。集合建立時可以存在兩個相同的項,但沒意義,最終形成的集合只會保留一個。

例:s={2,"veil",("a",5),frozenset({8,4,7}),"a"}

  集合是沒索引位置區分的,也不能分片或按步距分片。集合中每個資料都是獨一無二的,所以集合常被用於刪除重複的資料項(x=list(set(x)))。

1、集合常用函式:

       s.add(x)  新增x到集合s中;

       s.clear()  清空;

       s.pop()    移除集合中任意一項,如果為空了則返回產生KeyError異常;

       s.remove(x) 移除x項,如x不存在就產生KeyError異常;

       s.discard(x)  如果x 存在就移除掉該項;

       s.copy()   淺拷貝;  *

       s.different(t)s-t  返回一個新集合,其只包含s但不在集合t中;  *

       s.difference_update(t)s-=t  移除每一個在集合t但不在s中的項;

       s.intersection(t)s&t     返回s和t的交集;  *

2、集合聯合操作運算子結果:

       s|t,合集;s&t,交集;s-t,減去與t的交集;s^t,合集減去交集。

3、集合內涵(同列表內涵)

       {expression for item in iterable}

       {expression for item in iterable if condition}

4、固定集合(frozenset())

       一旦建立了就不可改變,同static,可用的函式只有那些不改變集合本身內容的函式(上已用*標註)。

 

三、對映型別(dict)

 

對映是鍵-值資料的無序組合。內建的對映型別有:dict(),collections.defaultdict();對於3.1以上的還有collections.OrderedDict(),它同dict()一樣,不過有索引序列。

對映的鍵只有可hash運算的型別才可使用,而值則可使用任意型別的資料。

1、字典的建立

d=dict(id=1948,name="washer",size=3)  #關鍵字引數

d={"id":1948,"name":"washer","size":3}   #面值

d=dict({"id":1948,"name":"washer","size":3})    #面值

d=dict([("id",1948),("name","washer"),("size",3)])  #序列

d=dict(zip(("id","name","size"),(1948,"washer",3)))  #序列

{}或用d=dict()來建立一個空字典

2、使用d["id"]則返回相應的值,如果此鍵不存在,則產生一個KeyError.

d["xx"]=34可新增一個項,如果此鍵已經存在,則會修改原始的值。

del d["xx"]會刪除鍵為"xx"的項,如果不存在則產生一個KeyError。

3、常用函式(全)

       d.clear()  清空

       d.copy()  淺拷貝

       d.pop(k,v) 返回k的值,並刪除k項,如果k不存在,就返回KeyError或者v(如v存在的話)

       d.popitem() 移除任意一對鍵-值,如果d為空就產生KeyError

       d.values()  返回字典中所有值的檢視

       d.keys()   返回字典所有鍵的檢視

       d.items()  返回字典所有(key,value)對的檢視

       d.get(k)   返回k的值,如果k不存在就返回None

       d.get(k,v)  返回k的值,如果k不存在就返回v

       d.setdefault(k,v) 同get(),如果k不存在就插入一個k項,值為None或者v(如果給了v)

       d.fromkeys(s,v) 返回一個dict,它的鍵為序列s的項,值為None或者v(如果給了v)

       d.update(a) 用a更新d,如果鍵已存在則更新值,如不存在則插入。a可以是dict也可以是(key,value)對的一個iterable.

for

4、對字典的迭代

       對鍵:for key in d:    print(key)

              或:for key in d.keys():   print(key)

       對值:for value in d.values():     print(value)

       對鍵-值:for key,value in d.items():    print(key,value)

              或:for item in d.items():    print(item[0],item[1])

5、字典鍵的檢視與項的檢視支援一些類似於集合的操作(集合處的聯合操作運算)

此可用in來檢視某個鍵是否存在於dict,也可用聯合操作運算檢視特定集合的鍵是否存在於dict,如下:

d={}.fromkeys("ABCD",3);  s=set("ACX"); matches=d.keys()&s  #matches=={'A','C'}

6、字典內涵

{keyexpression:valueexpression for key ,value in terable}

{keyexpression:valueexpression for key ,value in terable if condition}

例:一個字典的鍵-值反轉:inverted_d={v:k for k, v in d.items()}

7、預設字典(collectons.defaultdict())

預設字典永遠不會產生KeyError,當查詢的鍵不存在時,字典就會自動生成一個新的以此查詢鍵為鍵的項,其值為建立字典時設定的預設值。

例:words=collections.defaultdict(int),新增入此字典的預設值就會是數字0。傳入的int為工廠函式(也就是一個不帶括號、沒有引數的函式),以後可用lambda函式進行簡單設定。

8、有序字典(collctions.OrderedDict())

字典的資料項以插入的順序進行儲存,如果用了一個無序的字典來進行update(),得到的結果也會變成無序的。

do=collections.OderedDict([('z',5),(3,6),(8,'a')])或者先建一個空的,再一項一項的新增。

將一個普通字典轉換成有序字典:d=collections.OderedDict(sorted(d.items()))。

 

四、組合資料的迭代與複製

1、常見迭代操作符與函式:

       s+t  兩個序列的連線;

       s*n  返回n個s序列的連線的序列;

       x in s  判斷是否在內,not in;

       all(i)    如果iterable i中的每一項都評估為True,則返回True;

       any(i)  如果任意一項為True,則返回True;

       enumerate(i,start)通常用於for...in迴圈,提供一個(index,item)元組序列,其中的索引起始值為0或start;{相當於將一個序列i折分成單個,並給每個一個序列號,用(index,item),index為自動產生的序列號,item則依次為i每一項的值}

       len()   返回長度;

       max(i,key) 返回iterable i 中最大的項,如果給定的是key函式,就返回key(item)值最大的項;

       min(i,key)  同上;

       range(start,stop,step) 返回一個數字迭代子,左閉右開,如果沒給start,則從0開始;

       reversed(i) 反轉序列;

       sorted(i,key,reverse)   排序;reverse=True時進行逆序排列。當key存在時可以設定為需要的任意函式規則,甚至可以是自己構造的函式,如key=abs以絕對值排列,key=str.lower,以str中的lower()函式規則排序。sorted()排序只適用於所有資料項都可以進行互相比較的組合型別,如果有不同的型別則會產生一個TypeError。

       sum(i,start)  求和,start為可選

       zip(i1,...,iN)  返回元組的迭代子,使用迭代子i1到iN;i1-iN都是iterable資料組,例可參考dict的zip構造方式。只要有某個iterable中的元素用完,就終止迭代過程。

2、用a=iter(iterable結構)可以獲取一個迭代子,在每次迴圈時可用next(a)方法獲取下一個資料項,當結尾時會產生一個StopIteration異常。

3、組合資料型別的複製。

樣:b="sudent",a=b   這樣的用等號只是簡單的將b的值賦給了a,但b的值"student"在系統內並沒有被複製成2份,只是a和b都指向"student"這個值,無論是從a還是從b改變這個物件"student",另一個變數也會顯示出改變後的結果。要想複製出一個"student"的副本則可以用加上型別名:a=str(b);或者分片的方式a=b[:],因為提取分片時會產生一個副本。對於字典和集合型別則用copy()函式來實現。

       以上的方法都屬於淺拷貝,因為它只會複製物件的第一層內容。如果物件中還存在可變的iterable物件,它拷貝的只是iterable物件的引用地址,如果iterable從原物件改變了,拷貝物件的iterable部分也會跟著改變。如巢狀的列表:['a',['b','c']],複製此物件['b','c']部分時只是複製的一個引用地址。 如果要對此物件進行完全的複製則需用到深拷貝,import copy;       a=copy.deepcopy(b)

4、位置常量命名一般方法:WATER,TREE,MONEY=range(1,4);那麼這三個字元的值依次就為1,2,3

相關文章