第二章(提煉) 序列構成的陣列(三)

2021-10-04 17:58:28 字數 2934 閱讀 6485

python 程式設計師會預設序列是支援

+ 和

* 操作的。通常

+ 號兩側的序列由相同型別的資料所構成,在拼接的過程中,兩個被操作的序列都不會被修改,python

會新建乙個包含同樣型別資料的序列來作為拼接的結果。

如果想要把乙個序列複製幾份然後再拼接起來,更快捷的做法是把這個序列乘以乙個整數。+ 和 * 都遵循這個規律,不修改原有的操作物件,而是構建乙個全新的序列。

如果在 a * n

這個語句中,序列

a 裡的元素是對其他可變 物件的引用的話,你就需要格外注意了,因為這個式子的結果可能 會出乎意料。比如,你想用 my_list = * 3

來初始化乙個 由列表組成的列表,但是你得到的列表裡包含的 3

個元素其實是

3 個引用,而且這 3

個引用指向的都是同乙個列表。

演示1建立由列表組成的列表

上述操作等同於(每次迭代中新建了乙個list。作為新的一行新增到board中):

演示2含有3個指向同一物件的引用的列表是毫無用處的

上述錯誤示範等同於(追加同乙個物件3次到board列表):

2.1 +=和*=背後的故事

增量賦值運算子 +=

和 *= 的表現取決於它們的第乙個操作物件。+= 背後的特殊方法是 __iadd__ (用於「就地加法」)。但是如果乙個類沒有實現這個方法的話,python 會退一步呼叫 __add__ 。如:在a += b的執行過程中,如果 a

實現了

__iadd__

方法,就會呼叫這個方法。同時對可變序列來說,a

會就地改動,就像呼叫了 a.extend(b)

一樣。但是如果

a 沒有實現

__iadd__

的話,a += b 這個表示式的效果就變得跟

a = a + b

一樣了:首先計算

a + b,得到乙個新的物件,然後賦值給

a。也就是說,在這個表示式中,變數名會不會被關聯到新的物件,完全取決於這個型別有沒有實現 __iadd__ 這個方法。

總體來講,可變序列一般都實現了 __iadd__

方法,因此

+= 是就地加 法。而不可變序列根本就不支援這個操作,對這個方法的實現也就無從 談起。 上面所說的這些關於 +=

的概念也適用於

*=,不同的是,後者相對應的 是 __imul__。

演示3*=在可變和不可變序列上的對比

對不可變序列進行重複拼接操作的話,效率會很低,因為每次都有乙個新物件,而直譯器需要把原來物件中的元素先複製到新的物件裡,然後再追加新的元素。

str 是乙個例外,因為對字串做 +=

實在是太普遍了,所以

cpython

對它做了優化。為

str 初始化記憶體的時候,程式會為它留出額外的可擴充套件空間,因此進行增量操作的時候,並不會涉及複製原有字串到新位置這類操作。

2.2 乙個關於+=的謎題

上述**中,因為 tuple

不支援對它的元素賦值,所以會丟擲

typeerror 異常。但與此同時元組卻被改變了:t= (1, 2, [30, 40, 50, 60])。這是非常罕見的邊界情況,因此我們需要注意以下3點:

list.sort 方法會就地排序列表,也就是說不會把原列表複製乙份。這也是這個方法的返回值是 none 的原因。在這種情況下返回

none

其實是

python

的乙個慣例:如果乙個函式或者方法對物件進行的是就地改動,那它就應該返回 none

,好讓呼叫者知道傳入的引數發生了變動,而且並未產生新的物件。例如,random.shuffle 函式也遵守了這個慣例。(注:用返回 none 來表示就地改動這個慣例有個弊端,那就是呼叫者無法將其串聯起來。)

與 list.sort 相反的是內建函式 sorted

,它會新建乙個列表作為返回值。這個方法可以接受任何形式的可迭代物件作為引數,甚至包括不可

變序列或生成器。而不管 sorted

接受的是怎樣的引數,它最後都會返回乙個列表。

不管是 list.sort 方法還是

sorted

函式,都有兩個可選的關鍵字引數:

演示4list.sort()和sorted()的用法

已排序的序列可以用來進行快速搜尋,而標準庫的

bisect

模組給我們提供了二分查詢演算法。下一節會詳細講這個函式,順便還會看看bisect.insort 如何讓已排序的序列保持有序。

全域性變數 陣列 第二章 序列構成陣列

python 風格 序列的泛型操作,內建元組和對映型別,用縮進來架構的原始碼,無需變數宣告的強型別等.python 從 abc 語言繼承了用統一風格處理序列資料.資料結構都共用同一套操作 迭代,切片,排序,和拼接.容器序列 list,tuple,collections.deque 等能存放不同型別的...

第二章序列

序列是一種最基本的資料結構,資料結構是通過某種方式把很多資料元素組合在一起的集合 資料元素可以使數字,可以是字元,甚至可以是一些資料結構 內建序列 最重要的是列表和元組 字串 unicode字串 buffer物件 xrange物件 例 edward edward gimby 42 john john...

第二章 第三章

列舉和 define巨集的區別 define巨集常量是在預編譯階段進行簡單替換,列舉常量則是在編譯的時候確定其值。一般在編譯器裡,可以除錯列舉常量,但是不能除錯巨集常量。列舉可以一次定義大量相關的常量,而 define巨集一次只能定義乙個。聯合體 unionperdata 定義了乙個名為perdat...