Python 序列構成的數組(序列的增量賦值)

序列的增量賦值

增量賦值運算符 += 和 *= 的表現取決于它們的第一個操作對象。簡單起
見,我們把討論集中在增量加法(+=)上,但是這些概念對 *= 和其他
增量運算符來說都是一樣的。

+= 背后的特殊方法是 iadd (用于“就地加法”)。但是如果一個類
沒有實現這個方法的話,Python 會退一步調用 add 。考慮下面這
個簡單的表達式:

>>> a += b

如果 a 實現了 iadd 方法,就會調用這個方法。同時對可變序列
(例如 list、bytearray 和 array.array)來說,a 會就地改動,就
像調用了 a.extend(b) 一樣。但是如果 a 沒有實現 iadd 的話,a
+= b 這個表達式的效果就變得跟 a = a + b 一樣了:首先計算 a +
b,得到一個新的對象,然后賦值給 a。也就是說,在這個表達式中,
變量名會不會被關聯到新的對象,完全取決于這個類型有沒有實現
iadd 這個方法。

總體來講,可變序列一般都實現了 iadd 方法,因此 += 是就地加
法。而不可變序列根本就不支持這個操作,對這個方法的實現也就無從
談起。

上面所說的這些關于 += 的概念也適用于 *=,不同的是,后者相對應的
imul。關于 iaddimul,接下來有個小例子,展示的是 *= 在可變和不可變序列上的作用:

>>> l = [1, 2, 3]
>>> id(l)
4311953800 ?
>>> l *= 2
>>> l
[1, 2, 3, 1, 2, 3]
>>> id(l)
4311953800 ?
>>> t = (1, 2, 3)
>>> id(t)
4312681568 ?
>>> t *= 2
>>> id(t)
4301348296 ?

? 剛開始時列表的 ID。
? 運用增量乘法后,列表的 ID 沒變,新元素追加到列表上。
? 元組最開始的 ID。
? 運用增量乘法后,新的元組被創建。

對不可變序列進行重復拼接操作的話,效率會很低,因為每次都有一個
新對象,而解釋器需要把原來對象中的元素先復制到新的對象里,然后
再追加新的元素。

str 是一個例外,因為對字符串做 += 實在是太普遍了,所以 CPython 對它做了優化。為 str
初始化內存的時候,程序會為它留出額外的可擴展空間,因此進行增量操作的時候,并不會涉
及復制原有字符串到新位置這類操作。

我們已經認識了 += 的一般用法,下面來看一個有意思的邊界情況。這
個例子可以說是突出展示了“不可變性”對于元組來說到底意味著什么。

一個關于+=的謎題
讀讀完下面的代碼,然后回答這個問題:示例 2-14 中的兩個表達式到底
會產生什么結果? 回答之前不要用控制臺去運行這兩個式子。讀完下面的代碼,然后回答這個問題:示例 2-14 中的兩個表達式到底
會產生什么結果? 回答之前不要用控制臺去運行這兩個式子。
示例 2-14 一個謎題

>>> t = (1, 2, [30, 40])
>>> t[2] += [50, 60]

到底會發生下面 4 種情況中的哪一種?
a. t 變成 (1, 2, [30, 40, 50, 60])。
b. 因為 tuple 不支持對它的元素賦值,所以會拋出 TypeError 異常。
c. 以上兩個都不是。
d. a 和 b 都是對的。

我剛看到這個問題的時候,異常確定地選擇了 b,但其實答案是 d,也
就是說 a 和 b 都是對的!示例 2-15 是運行這段代碼得到的結果,用的
Python 版本是 3.4,但是在 2.7 中結果也一樣。

示例 2-15 沒人料到的結果:t[2] 被改動了,但是也有異常拋出

>>> t = (1, 2, [30, 40])
>>> t[2] += [50, 60]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'tuple' object does not support item assignment
>>> t
(1, 2, [30, 40, 50, 60])

Python Tutor(http://www.pythontutor.com)是一個對 Python 運行原理進行
可視化分析的工具。圖 2-3 里是兩張截圖,分別代表示例 2-15 中 t 的
初始和最終狀態。

image

下面來看看示例 2-16 中 Python 為表達式 s[a] += b 生成的字節碼,可
能這個現象背后的原因會變得清晰起來。
示例 2-16 s[a] = b 背后的字節碼

>>> dis.dis('s[a] += b')
1 0 LOAD_NAME 0(s)
3 LOAD_NAME 1(a)
6 DUP_TOP_TWO
7 BINARY_SUBSCR ?
8 LOAD_NAME 2(b)
11 INPLACE_ADD ?
12 ROT_THREE
13 STORE_SUBSCR ?
14 LOAD_CONST 0(None)
17 RETURN_VALUE

? 將 s[a] 的值存入 TOS(Top Of Stack,棧的頂端)。
? 計算 TOS += b。這一步能夠完成,是因為 TOS 指向的是一個可變對
象(也就是示例 2-15 里的列表)。
? s[a] = TOS 賦值。這一步失敗,是因為 s 是不可變的元組(示例 2-15 中的元組 t)。
這其實是個非常罕見的邊界情況,在 15 年的 Python 生涯中,我還沒見
過誰在這個地方吃過虧。
至此我得到了 3 個教訓。
不要把可變對象放在元組里面。
增量賦值不是一個原子操作。我們剛才也看到了,它雖然拋出了異
常,但還是完成了操作。
查看 Python 的字節碼并不難,而且它對我們了解代碼背后的運行機
制很有幫助。
在見證了 + 和 * 的微妙之處后,我們把話題轉移到序列類型的另一個重
要部分上:排序。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/75059.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/75059.shtml
英文地址,請注明出處:http://en.pswp.cn/web/75059.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

GEO, TCGA 等將被禁用?!這40個公開數據庫可能要小心使用了

GEO, TCGA 等將被禁用&#xff1f;&#xff01;這40個公開數據庫可能要小心使用了 最近NIH公共數據庫開始對中國禁用的消息鬧得風風火火&#xff1a; 你認為研究者上傳到 GEO 數據庫上的數據會被禁用嗎&#xff1f; 單選 會&#xff0c;畢竟占用存儲資源 不會&#xff0c;不…

【如何自建MCP服務器?從協議原理到實踐的全流程指南】

文章目錄 如何自建MCP服務器&#xff1f;從協議原理到實踐的全流程指南一、MCP協議是什么&#xff1f;核心架構 二、為什么要自建MCP服務器&#xff1f;1. 突破LLM的固有局限2. 實現個性化功能擴展3. 確保數據隱私安全 三、手把手搭建MCP服務器&#xff08;Python示例&#xff…

鴻蒙開發_ARKTS快速入門_語法說明_渲染控制---純血鴻蒙HarmonyOS5.0工作筆記012

然后我們再來看渲染控制 首先看條件渲染,其實就是根據不同的狀態,渲染不同的UI界面 比如下面這個暫停 開啟播放的 可以看到就是通過if 這種條件語句 修改狀態變量的值 然后我們再來看這個, 下面點擊哪個,上面橫線就讓讓他顯示哪個 去看一下代碼 可以看到,有兩個狀態變量opt…

【Java設計模式】第3章 軟件設計七大原則

3-1 本章導航 學習開辟原則(基礎原則)依賴倒置原則單一職責原則接口隔離原則迪米特法則(最少知道原則)里氏替換原則合成復用原則(組合復用原則)核心思想: 設計原則需結合實際場景平衡,避免過度設計。設計模式中可能部分遵循原則,需靈活取舍。3-2 開閉原則講解 定義 軟…

JVM即時編譯(JIT)

JVM基礎回顧 Java 作為一門高級程序語言&#xff0c;由于它自身的語言特性&#xff0c;它并非直接在硬件上運行&#xff0c;而是通過編譯器(前端編譯器)將 Java 程序轉換成該虛擬機所能識別的指令序列&#xff0c;也就是字節碼&#xff0c;然后運行在虛擬機之上的&#xff1b;…

剛體碰撞檢測與響應(C++實現)

本文實現一個經典的物理算法&#xff1a;剛體碰撞檢測與響應。這個算法用于檢測兩個剛體&#xff08;如矩形或圓形&#xff09;是否發生碰撞&#xff0c;并在碰撞時更新它們的速度和位置。我們將使用C來實現這個算法&#xff0c;并結合**邊界框&#xff08;Bounding Box&#x…

常用的國內鏡像源

常見的 pip 鏡像源 阿里云鏡像&#xff1a;https://mirrors.aliyun.com/pypi/simple/ 清華大學鏡像&#xff1a;https://pypi.tuna.tsinghua.edu.cn/simple 中國科學技術大學鏡像&#xff1a;https://pypi.mirrors.ustc.edu.cn/simple/ 豆瓣鏡像&#xff1a;https://pypi.doub…

鴻蒙小案例-京東登錄

效果 代碼實現 Entry Component struct Index {build() {Column() {Row() {Image($r(app.media.jd_cancel)).width(20)Text(幫助).fontSize(16).fontColor(#666)}.width(100%).justifyContent(FlexAlign.SpaceBetween)Image($r(app.media.jd_logo)).height(250).width(250)// …

《 Scikit-learn與MySQL的深度協同:構建智能數據生態系統的架構哲學》

在機器學習工程實踐中&#xff0c;數據存儲與模型訓練的割裂始終是制約算法效能的關鍵瓶頸。Scikit-learn作為經典機器學習庫&#xff0c;其與MySQL的深度協同并非簡單的數據管道連接&#xff0c;而是構建了一個具備自組織能力的智能數據生態系統。這種集成突破了傳統ETL流程的…

華為AI-agent新作:使用自然語言生成工作流

論文標題 WorkTeam: Constructing Workflows from Natural Language with Multi-Agents 論文地址 https://arxiv.org/pdf/2503.22473 作者背景 華為&#xff0c;北京大學 動機 當下AI-agent產品百花齊放&#xff0c;盡管有ReAct、MCP等框架幫助大模型調用工具&#xff0…

關于軟件bug描述

軟件缺陷&#xff08;Defect&#xff09;&#xff0c;常常又被叫做Bug。 所謂軟件缺陷&#xff0c;即為計算機軟件或程序中存在的某種破壞正常運行能力的問題、錯誤&#xff0c;或者隱藏的功能缺陷。缺陷的存在會導致軟件產品在某種程度上不能滿足用戶的需要。IEEE729-1983對缺…

【元表 vs 元方法】

元表 vs 元方法 —— 就像“魔法書”和“咒語”的關系 1. 元表&#xff08;Metatable&#xff09;&#xff1a;魔法書 是什么&#xff1f; 元表是一本**“規則說明書”**&#xff0c;它本身是一個普通的 Lua 表&#xff0c;但可以綁定到其他表上&#xff0c;用來定義這個表應該…

Spring Boot 通過全局配置去除字符串類型參數的前后空格

1、問題 避免前端輸入的字符串參數兩端包含空格&#xff0c;通過統一處理的方式&#xff0c;trim掉空格 2、實現方式 /*** 去除字符串類型參數的前后空格* author yanlei* since 2022-06-14*/ Configuration AutoConfigureAfter(WebMvcAutoConfiguration.class) public clas…

C語言核心知識點整理:結構體對齊、預處理、文件操作與Makefile

目錄 結構體的字節對齊預處理指令詳解文件操作基礎Makefile自動化構建總結 1. 結構體的字節對齊 字節對齊原理 內存對齊&#xff1a;CPU訪問內存時&#xff0c;對齊的地址能提高效率。操作系統要求變量按類型大小對齊。對齊規則&#xff1a; 每個成員的起始地址必須是min(成…

VBA+BOS單據+插件,解決計劃任務跟蹤的問題之二:導入ERP

第二步&#xff0c;就是要將拆分好的任務導入ERP了 1、將建一個BOS單據叫“任務池”&#xff0c;大概是這樣的 然后在拆分工具中進行導數據&#xff0c;點擊“數據導出準備”&#xff0c;跳轉到“導入ERP”界面&#xff0c;然后點“獲取數據”&#xff0c;將拆分好的數據轉過來…

使用uglifyjs對靜態引入的js文件進行壓縮

前言 因為有時候js文件沒有npm包&#xff0c;或者需要修改&#xff0c;只能引入靜態的js&#xff0c;那么這個時候就可以對js進行壓縮了。我其實想通過vite、webpack等插件進行壓縮的&#xff0c;可是他都不能定位到public目錄下面的文件&#xff0c;所以我只能自己壓縮了。編…

藍橋杯 web 水果拼盤 (css3)

做題步驟&#xff1a; 看結構&#xff1a;html 、css 、f12 分析: f12 查看元素&#xff0c;你會發現水果的高度剛好和拼盤的高度一樣&#xff0c;每一種水果的盤子剛好把頁面填滿了&#xff0c;所以咱們就只要讓元素豎著排列&#xff0c;加上是豎著&#xff0c;排不下的換行…

差分音頻轉單端音頻單電源方案

TI LMV321介紹 TI的LMV321是單通道的低壓軌到軌輸出運算放大器&#xff0c;適用于需要低工作壓、節省空間和低成本的應用。 其中&#xff0c;芯片設計中的軌到軌輸出&#xff08;Rail-to-Rail Output&#xff09; 是指通過特定的電路設計&#xff0c;使芯片&#xff08;如運算…

Pandas 庫

Pandas 是一個開源的數據分析和數據處理庫&#xff0c;它是基于 Python 編程語言的。 Pandas 提供了易于使用的數據結構和數據分析工具&#xff0c;特別適用于處理結構化數據&#xff0c;如表格型數據 Pandas 是數據科學和分析領域中常用的工具之一&#xff0c;它使得用戶能夠…

Vue 3 的<Teleport>功能與用法

Vue 3 的 <Teleport> 功能與用法 1. 基本用法 <Teleport> 是 Vue 3 的一個內置組件&#xff0c;允許將組件的內容渲染到 DOM 中的任意位置&#xff0c;而不改變其邏輯結構。以下是基本用法&#xff1a; 定義目標 DOM 元素&#xff1a;<div id"teleport-…