新聞中心
本篇內(nèi)容主要講解“如何解決序列賦值引發(fā)的Python列表陷進(jìn)”,感興趣的朋友不妨來(lái)看看。本文介紹的方法操作簡(jiǎn)單快捷,實(shí)用性強(qiáng)。下面就讓小編來(lái)帶大家學(xué)習(xí)“如何解決序列賦值引發(fā)的Python列表陷進(jìn)”吧!

目前累計(jì)服務(wù)客戶數(shù)千家,積累了豐富的產(chǎn)品開(kāi)發(fā)及服務(wù)經(jīng)驗(yàn)。以網(wǎng)站設(shè)計(jì)水平和技術(shù)實(shí)力,樹(shù)立企業(yè)形象,為客戶提供做網(wǎng)站、成都網(wǎng)站制作、網(wǎng)站策劃、網(wǎng)頁(yè)設(shè)計(jì)、網(wǎng)絡(luò)營(yíng)銷、VI設(shè)計(jì)、網(wǎng)站改版、漏洞修補(bǔ)等服務(wù)。成都創(chuàng)新互聯(lián)始終以務(wù)實(shí)、誠(chéng)信為根本,不斷創(chuàng)新和提高建站品質(zhì),通過(guò)對(duì)領(lǐng)先技術(shù)的掌握、對(duì)創(chuàng)意設(shè)計(jì)的研究、對(duì)客戶形象的視覺(jué)傳遞、對(duì)應(yīng)用系統(tǒng)的結(jié)合,為客戶提供更好的一站式互聯(lián)網(wǎng)解決方案,攜手廣大客戶,共同發(fā)展進(jìn)步。
+
+是指把兩個(gè)序列的元素拼接在一起。通常+號(hào)兩側(cè)的序列由相同類型的數(shù)據(jù)所構(gòu)成,在拼接的過(guò)程中,兩個(gè)被操作的序列都不會(huì)被修改,Python會(huì)新建一個(gè)包含同樣類型數(shù)據(jù)的序列作為拼接的結(jié)果。比如:
a = [1] b = [2] c = a + b print(a, b, c) print(id(a), id(b), id(c))
結(jié)果為:
[1] [2] [1, 2] 2409610524480 2409610523520 2409610523648
*
如果想要把一個(gè)序列復(fù)制幾份然后再拼接起來(lái),更快捷的做法是把這個(gè)序列乘以一個(gè)整數(shù)。同樣,這個(gè)操作會(huì)產(chǎn)生一個(gè)新序列:
>>> l = [1] >>> l * 5 [1, 1, 1, 1, 1] >>> 5 * "a" 'aaaaa'
+和*都遵循這個(gè)規(guī)律,不修改原有的操作對(duì)象,而是構(gòu)建一個(gè)全新的序列。
列表套列表的陷進(jìn)
猜猜這個(gè)結(jié)果會(huì)是啥:
x = ["x"] my_list = [x] * 3 print(my_list) # [['x'], ['x'], ['x']] x2 = my_list[2] x2[0] = "y" print(my_list)
講道理,應(yīng)該是[['x'], ['x'], ['y']],但是錯(cuò)了,實(shí)際是:
[['y'], ['y'], ['y']]
Unbelievable!給my_list的最后一個(gè)元素的列表賦值,結(jié)果所有三個(gè)元素的列表都被賦值了!這反映出my_list這三個(gè)元素不是3個(gè)列表,而是3個(gè)列表引用,指向了同一個(gè)相同的列表。相當(dāng)于:
x = ["x"] my_list = [] for i in range(3): my_list.append(x) # 追加相同對(duì)象 x2 = my_list[2] x2[0] = "y" print(my_list) # [['y'], ['y'], ['y']]
每次都追加了同一個(gè)對(duì)象到my_list。如果想生成3個(gè)不同列表,那么需要在每次迭代中新建列表:
my_list = [] for i in range(3): x = ["x"] # 新建列表 my_list.append(x) x2 = my_list[2] x2[0] = "y" print(my_list) # [['x'], ['x'], ['y']]
這樣就符合預(yù)期了??梢杂昧斜硗茖?dǎo)簡(jiǎn)化代碼:
x = ["x"] my_list = [x for i range(3)] x2 = my_list[2] x2[0] = "y" print(my_list) # [['x'], ['x'], ['y']]
教訓(xùn):
新建列表中的列表,使用列表推導(dǎo),不要使用*運(yùn)算符。
如果a * n這個(gè)語(yǔ)句中,序列a里的元素是對(duì)其他可變對(duì)象的引用的話,就需要格外注意了,這可能不是你想要的效果。
+=
a += b雖然意思是a = a + b,但是它背后的特殊方法是__iadd__,如果一個(gè)類沒(méi)有實(shí)現(xiàn)這個(gè)方法的話,Python才會(huì)退一步調(diào)用__add__。__iadd__方法會(huì)直接在原對(duì)象中追加,__add__方法會(huì)先生成新對(duì)象再賦值。
*=
+=的這些概念也適用于*=,只是后者對(duì)應(yīng)的是__imul__。追加還是新對(duì)象,在作用到可變序列和不可變序列時(shí)效果明顯,示例:
# 可變序列,追加 >>> l = [1, 2, 3] >>> id(l) 2135319475136 >>> l *= 2 >>> l [1, 2, 3, 1, 2, 3] >>> id(l) 2135319475136 # id一樣 # 不可變序列,新對(duì)象 >>> t = (1, 2, 3) >>> id(t) 2135322139520 >>> t *= 2 >>> id(t) 2135321695424 # id不一樣
元組套列表的陷進(jìn)
>>> t = (1, 2, [30, 40]) >>> t[2] += [50, 60]
猜猜會(huì)發(fā)生下面4種情況中的哪一種?a.t變成(1, 2, [30, 40, 50, 60])b.因?yàn)閠uple不支持對(duì)它的元素賦值,所以會(huì)拋出TypeError異常c.以上兩個(gè)都不是d.a和b都是對(duì)的因?yàn)樵M不能賦值,所以我會(huì)毫不猶豫的選擇b。但實(shí)際上答案是d!a和b都是對(duì)的,既會(huì)賦值成功,也會(huì)報(bào)錯(cuò):
>>> t = (1, 2, [30, 40]) >>> t[2] += [50, 60] Traceback (most recent call last): File "", line 1, inTypeError: 'tuple' object does not support item assignment >>> t (1, 2, [30, 40, 50, 60])
Oh No!為什么?一、賦值成功,因?yàn)閠[2]指向的是一個(gè)可變對(duì)象(列表[30, 40]),可變對(duì)象是能賦值的。二、報(bào)錯(cuò),因?yàn)榭勺儗?duì)象賦值給了不可變對(duì)象(元組t),不可變對(duì)象不能賦值。
寫(xiě)成t[2].extend([50, 60])能避免這個(gè)異常。
教訓(xùn):
不要把可變對(duì)象放在元組里面。
+=不是一個(gè)原子操作,雖然拋出了異常,但還是完成了操作。
這位巴西作者說(shuō)到,在他15年的Python生涯中,他還沒(méi)見(jiàn)過(guò)誰(shuí)在這個(gè)地方吃過(guò)虧。
到此,相信大家對(duì)“如何解決序列賦值引發(fā)的Python列表陷進(jìn)”有了更深的了解,不妨來(lái)實(shí)際操作一番吧!這里是創(chuàng)新互聯(lián)網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!
網(wǎng)頁(yè)題目:如何解決序列賦值引發(fā)的Python列表陷進(jìn)
轉(zhuǎn)載源于:http://www.dlmjj.cn/article/pscopj.html


咨詢
建站咨詢
