python 用統一的風格去處理序列資料。不管是哪種資料結構,字串、列表、位元組序列、陣列、xml 元素,抑或是資料庫查詢結果,它們都共用一套豐富的操作:迭代、切片、排序,還有拼接。
python 標準庫用 c 實現了豐富的序列型別,列舉如下。
序列型別還能按照能否被修改來分類。
下圖顯示了可變序列(mutablesequence)和不可變序列(sequence)的差異,同時也
能看出前者從後者那裡繼承了一些方法。
[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-vcjtf0vm-1612281306648)(d:\note\fluentpython\img\2.1.png)]
列表推導可以幫助我們把乙個序列或是其他可迭代型別中的元素過濾或是加工,然後再新建乙個列表。
列表推導式:
l = [function(i) for i in iterable]
生成器推導式:
t = (function(i) for i in iterable)
# 用生成器表示式初始化元組和陣列
>>
> symbols =
'$¢£¥€¤'
>>
>
tuple
(ord
(symbol)
for symbol in symbols)(36
,162
,163
,165
,8364
,164
)>>
>
import array
>>
> array.array(
'i',
(ord
(symbol)
for symbol in symbols)
)array(
'i',[36
,162
,163
,165
,8364
,164
])
列表推導、生成器表示式,以及同它們很相似的集合(set)推導和字典(dict)推導,在 python 3 中都有了自己的區域性作用域,就像函式似的。表示式內部的變數和賦值只在區域性起作用,表示式的上下文裡的同名變數還可以被正常引用,區域性變數並不會影響到它們。
[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-u7fmhcak-1612281306651)(d:\note\fluentpython\img\2.2.png)]
[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-dxvhedob-1612281306652)(d:\note\fluentpython\img\2.3.png)]
元組其實是對資料的記錄:元組中的每個元素都存放了記錄中乙個欄位的資料,外加這個
欄位的位置。正是這個位置資訊給資料賦予了意義。
如果只把元組理解為不可變的列表,那其他資訊——它所含有的元素的總數和它們的位
置——似乎就變得可有可無。但是如果把元組當作一些欄位的集合,那麼數量和位置資訊
就變得非常重要了。
[外鏈轉存失敗,源站可能有防盜煉機制,建議將儲存下來直接上傳(img-beijfzyx-1612281306654)(d:\note\fluentpython\img\2.4.png)]
兩種常見形式:
⭐運算子*****
運算子*****把乙個可迭代物件拆開作為函式的引數:
>>
>
divmod(20
,8)(
2,4)
>>
> t =(20
,8)>>
>
divmod
(*t)(2
,4)>>
> quotient, remainder =
divmod
(*t)
>>
> quotient, remainder (2
,4)
用*來處理剩下的元素,在 python 中,函式用*args
來獲取不確定數量的引數算是一種經典寫法了:
>>
> a, b,
*rest =
range(5
)>>
> a, b, rest (0
,1,[
2,3,
4])>>
> a, b,
*rest =
range(3
)>>
> a, b, rest (0
,1,[
2])>>
> a, b,
*rest =
range(2
)>>
> a, b, rest (0
,1,[
])
在平行賦值中,* 字首只能用在乙個變數名前面,但是這個變數可以出現在賦值表示式的任意位置
collections.namedtuple 是乙個工廠函式,它可以用來構建乙個帶欄位名的元組和乙個有
名字的類——這個帶名字的類對除錯程式有很大幫助。
用 namedtuple 構建的類的例項所消耗的記憶體跟元組是一樣的,因為欄位名都被存在對應的類裡面。這個例項跟普通的物件例項比起來也要小一些,因為python 不會用dict來存放這些例項的屬性。
>>
>
from collections import namedtuple
>>
> city = namedtuple(
'city'
,'name country population coordinates'
)>>
> tokyo = city(
'tokyo'
,'jp'
,36.933,(
35.689722
,139.691667))
>>
> tokyo
city(name=
'tokyo'
, country=
'jp'
, population=
36.933
, coordinates=
(35.689722
,139.691667))
>>
> tokyo.population
36.933
>>
> tokyo.coordinates
(35.689722
,139.691667
)>>
> tokyo[1]
'jp'
>>
> city._fields
('name'
,'country'
,'population'
,'coordinates'
)>>
> latlong = namedtuple(
'latlong'
,'lat long'
)>>
> delhi_data =
('delhi ncr'
,'in'
,21.935
, latlong(
28.613889
,77.208889))
>>
> delhi = city._make(delhi_data)
>>
> delhi._asdict(
)
ordereddict([(
'name'
,'delhi ncr'),
('country'
,'in'),
('population'
,21.935),
('coordinates'
, latlong(lat=
28.613889
,long
=77.208889))
])>>
>
for key, value in delhi._asdict(
).items():
print
(key +
':', value)
name: delhi ncr
country: in
population:
21.935
coordinates: latlong(lat=
28.613889
,long
=77.208889
)
除了從普通元組那裡繼承來的屬性之外,具名元組還有一些自己專有的屬性,幾個最有用的:_fields 類屬性、類方法_make(iterable)
和例項方法_asdict()
[start:stop:step]
對seq[start:stop:step]
進 行 求 值 的 時 候,python 會 調 用seq.__getitem__(slice(start, stop, step))
。
在 python 裡,像列表(list)、元組(tuple)和字串(str)這類序列型別都支援切片操作,但是實際上切片操作比人們所想象的要強大很多。
如果賦值的物件是乙個切片,那麼賦值語句的右側必須是個可迭代物件。即便只有單獨乙個值,也要把它轉換成可迭代的序列。
y_list[x:]` 就可以了
如果賦值的物件是乙個切片,那麼賦值語句的右側必須是個可迭代物件。即便只有單獨
乙個值,也要把它轉換成可迭代的序列。
2序列比對問題
str1 abdad str2 bacd 兩字串進行序列比對,定義乙個可以用來衡量比對效能的得分函式 令f x,y 表示x與y比對的得分。假設x和y都是字元,如果x與y相同,那麼f x,y 2,如果x與y不同,那麼f x,y 1,如果x或y是 那麼f x,y 1。str1和str2的2序列比對問題是...
STL學習2 序列容器
三種 vector,list,queue 基礎 陣列,鍊錶,陣列 支援函式 front,back,push back,pop back 可以動態的改變它的大小,可以彼此賦值,但陣列表示位址常量就沒這功能。vector就像陣列一樣,是連續的。在末尾插入非常高效,中間就不行。要想經常在兩端插入刪除,最好...
入門訓練 2 序列求和
問題描述 求1 2 3 n的值。輸入格式 輸入包括乙個整數n。輸出格式 輸出一行,包括乙個整數,表示1 2 3 n的值。樣例輸入 4樣例輸出 10樣例輸入 100說明 有一些試題會給出多組樣例輸入輸出以幫助你更好的做題。一般在提交之前所有這些樣例都需要測試通過才行,但這不代表這幾組樣例資料都正確了你...