Python 多變量賦值問題小結
今天在刷鏈表反轉題的時候,遇到了兩段看起來幾乎一樣的代碼,結果一個能正確反轉鏈表,一個卻不行。仔細研究后發(fā)現(xiàn),問題出在 Python 的多變量賦值順序上 —— 這個平時沒太在意的細節(jié),在操作鏈表指針時居然能造成這么大的影響。記錄一下我的分析過程,免得以后再踩類似的坑。
問題背景:兩段 “相似” 的反轉代碼
先看這兩段代碼,都是用迭代法反轉單鏈表:
代碼 1(能正確反轉):
def reverseList(head):
last = None
while head:
# 關鍵賦值行
last, head.next, head = head, last, head.next
return last
代碼 2(無法正確反轉):
def reverseList(head):
last = None
while head:
# 關鍵賦值行(順序不同)
head, head.next, last = head.next, last, head
return last
第一眼看上去,只是左側變量的賦值順序變了,右側的值好像還是那幾個。但實際運行時,代碼 1 能得到正確的反轉鏈表,代碼 2 卻會返回錯誤結果(比如鏈表斷裂、部分節(jié)點丟失)。這到底是為什么?
核心原因:Python 多變量賦值的 “秘密”
在 Python 里,多變量賦值的執(zhí)行邏輯是 “先計算右側所有表達式的值,再一次性賦值給左側變量”。也就是說,右側的值都是基于賦值前的原始狀態(tài)計算的,不會被左側的中間賦值影響。
但這一點,需要注意的是 “=”右側是獲取值,所以可以理解為完全并行執(zhí)行的。但是左側是改變值,這就意味著是會順序影響
逐行分析:兩段代碼的執(zhí)行差異
我們用一個簡單的鏈表1->2->3來模擬執(zhí)行過程,看看兩段代碼的區(qū)別。
代碼 1 的執(zhí)行邏輯(正確)
關鍵賦值行:last, head.next, head = head, last, head.next
拆解步驟(每次循環(huán)):
- 先算右側值(基于當前原始狀態(tài)):
- 第一個值:
head(當前節(jié)點,比如第一輪是 1) - 第二個值:
last(上一個節(jié)點,初始是 None) - 第三個值:
head.next(下一個節(jié)點,第一輪是 2)
- 再給左側賦值:
last= 第一個值(當前節(jié)點 1)→ 現(xiàn)在 last 指向 1head.next= 第二個值(原 last,即 None)→ 節(jié)點 1 的 next 指向 None(完成反轉第一步)head= 第三個值(下一個節(jié)點 2)→ 移動 head 到下一個節(jié)點,繼續(xù)循環(huán)
整個過程中,“反轉當前節(jié)點指針” 和 “移動 head 到下一個節(jié)點” 是基于原始值操作的,互不干擾。比如不會因為 head 移動了,導致當前節(jié)點的指針沒反轉。
代碼 2 的執(zhí)行邏輯(錯誤)
關鍵賦值行:head, head.next, last = head.next, last, head
同樣用1->2->3模擬:
- 先算右側值(基于當前原始狀態(tài)):
- 第一個值:
head.next(下一個節(jié)點 2) - 第二個值:
last(初始 None) - 第三個值:
head(當前節(jié)點 1)
- 再給左側賦值:
head= 第一個值(下一個節(jié)點 2)→ 此時 head 已經指向 2 了head.next= 第二個值(原 last,即 None)→ 注意!這里的 head 已經是 2 了,所以實際是把節(jié)點 2 的 next 改成了 Nonelast= 第三個值(原 head,即節(jié)點 1)→ last 指向 1
這就出問題了:原本應該反轉 “當前節(jié)點 1 的指針”,結果因為先移動了 head 到 2,導致實際修改的是 “節(jié)點 2 的指針”。節(jié)點 1 的指針根本沒反轉,后續(xù)循環(huán)也再也碰不到節(jié)點 1 了,鏈表直接從 1 這里斷了。
到此這篇關于Python 多變量賦值問題的文章就介紹到這了,更多相關Python 多變量賦值內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
Python爬蟲實戰(zhàn)之用selenium爬取某旅游網站
上一篇我們已經知道怎么簡單使用selenium了,那么我們就從這篇博客來動手爬取網站吧,文中有非常詳細的代碼示例,需要的朋友可以參考下2021-06-06
anaconda如何創(chuàng)建和刪除環(huán)境
這篇文章主要介紹了anaconda如何創(chuàng)建和刪除環(huán)境,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04
關于Python核心框架tornado的異步協(xié)程的2種方法詳解
今天小編就為大家分享一篇關于Python核心框架tornado的異步協(xié)程的2種方法詳解,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2019-08-08

