日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > python >内容正文

python

python长度为n的list_python “list*n”的坑你得注意

發布時間:2025/3/13 python 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python长度为n的list_python “list*n”的坑你得注意 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

很多時候我們會用‘listn’的方式來快速得到一個重復元素的新list,比如:

[2]5 = [2, 2, 2, 2, 2]

[0,1]10 = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

[[0],1]10 = [[0], 1, [0], 1, [0], 1, [0], 1, [0], 1]

……

顯然‘list×n’是將原list里面的所有元素整體復制n次后形成一個新的list。

但是特別注意:如果原list內部元素為“可變對象”(列表、字典、集合),則不會真正復制n份,而是傳遞n個引用給新的list,他們都指向原來的對象,當原list內部元素的元素改變時,新list內部對應元素也跟著變化(同樣新list內部元素的元素變化時,原list也變化);如果原list內部元素為“不可變對象”(數字,字符串,元祖),則不存在這個問題。

下面用詳細例子說明兩者的區別:

1)list內部為可變對象

請看下面例子:

列表a的元素是一個列表(可變對象),b是通過a復制得到的新列表。

a = [['1']]

b = a * 3

print('a={}'.format(a))

print('b={}'.format(b))

# 輸出:

a=[['1']]

b=[['1'], ['1'], ['1']]

下圖展示了a和b之間的關系,可見b并沒有獨立復制一個對象,而和a指向同一個對象。

新建 Microsoft Visio 繪圖.jpg

在前述代碼的基礎上通過a和b來修改內部列表的元素(注意是內部列表的元素),結果發現無論哪種情況,a和b都會同時變化:

a[0].extend([0]) #case 1

#a[0].append(0) #case 2

#a[0][0] = '2' #case 3

#b[0].extend([0]) #case 4

#b[0].append(0) #case 5

#b[0][0] = '2' #case 6

print('a={}'.format(a))

print('b={}'.format(b))

# 輸出:

a=[['1', 0]]

b=[['1', 0], ['1', 0], ['1', 0]]

a=[['2']]

b=[['2'], ['2'], ['2']]

上述六種情況分兩大類,其內部存儲結構如下圖,清晰解釋了為什么a和b同時變化了。從圖中可以看出,改變內部list(也就是圖中的“中間list”)的元素,實際加上就是改變了最底層元素,而a和b是共享的,因此會同時變化。

新建 Microsoft Visio 繪圖2.jpg

繼續往下看,下例中只通過改變最外層list的元素,而不對內部list的元素操作,從結果可以看出,無論是單獨改變a還是b,兩者都不會相互影響,b內部元素之間也沒有相互影響:

#case1

a[0] = ['4']

print('a={}'.format(a))

print('b={}'.format(b))

# 輸出:

a=[['4']]

b=[['1'], ['1'], ['1']]

#case2

b[0] = ['4']

print('a={}'.format(a))

print('b={}'.format(b))

# 輸出:

a=[['1']]

b=[['4'], ['1'], ['1']]

下圖展示了為什么會出現這種結果,a[0] = ['4']實際就是將a[0]指向了一個新的對象,而b中所有元素仍然指向原來的中間list,因此a變了,b沒有變。同理b[0] = ['4']也只是將b[0]指向了一個新的對象,而b中的其他元素和a都還指向原來的對象,因此也不會變。

新建 Microsoft Visio 繪圖3.jpg

前述例子中最外層list的的內部元素是list,如果內部元素換成字典或集合,結果也一樣,比如字典(其內部存儲機制與前面完全相同):

a = [{'age':10}]

b = a*3

print('a={}'.format(a))

print('b={}'.format(b))

# 輸出,這沒問題

a=[{'age': 10}]

b=[{'age': 10}, {'age': 10}, {'age': 10}]

#通過a和b來改變他們內部元素的值,即改變字典的值

a[0]['age'] = 20

#b[0]['age'] = 20

print('a={}'.format(a))

print('b={}'.format(b))

# 輸出,可見,a和b同時變了

a=[{'age': 20}]

b=[{'age': 20}, {'age': 20}, {'age': 20}]

#通過將a和b元素指向新的元素,

a[0] = {'name':'Lili'}

print('a={}'.format(a))

print('b={}'.format(b))

# 輸出,可見,只有a變了,

a=[{'name': 'Lili'}]

b=[{'age': 20}, {'age': 20}, {'age': 20}]

a=[{'age': 20}]

b=[{'name': 'Lili'}, {'age': 20}, {'age': 20}]

2)list內部為不可變對象

前述情況中,list內部的元素都是可變對象(列表,字典、集合),例如[[],[],[]]或[{},{},{}]

如果內部元素是不可變對象(字符串,數字,元組),例如['a','b']或[1,3],那問題就簡單了,完成不存在前述情況,內部存儲結構也很簡單。

請看下例:

a = ['cgx']

b = a*3

print('a={}'.format(a))

print('b={}'.format(b))

# 輸出,這沒問題

a=['cgx']

b=['cgx', 'cgx', 'cgx']

上述過程的存儲過程如下:

新建 Microsoft Visio 繪圖.jpg

我們企圖通過下面方式來改變內部元素是行不通的,可以通過a[0][0]或b[0][0]來得元素“c”,但企圖通過 a[0][0] = 'C'和b[0][0] = 'C'來將原來的‘c’變為“C”,這是行不通的,因為字符串屬于不可變對象,python禁止這種操作。

a[0][0] = 'C'

b[0][0] = 'C'

---------------------------------------------------------------------------

TypeError Traceback (most recent call last)

in

4 print('b={}'.format(b))

5

----> 6 a[0][0] = 'C'

7 b[0][0] = 'C'

8 # print('a={}'.format(a))

TypeError: 'str' object does not support item assignment

如果只是改變最外層元素(或者說將最外層list元素指向新的對象),那是沒什么問題的,這跟前面可變對象的情況沒什么區別,比如:

a[0] = 'Li'

#b[0] = 'Li'

print('a={}'.format(a))

print('b={}'.format(b))

#輸出

a=['Li']

b=['cgx', 'cgx', 'cgx']

a=['cgx']

b=['Li', 'cgx', 'cgx']

可見,通過a[0] = 'Li'或b[0] = 'Li'的操作,僅僅只是改變了a和b最外層單個元素的指向,不會影響其他元素。該過程如下圖所示:

新建 Microsoft Visio 繪圖.jpg

當list的內部元素為“數字”或“元組”時,情況與上述‘字符串’完全相同,此處不再贅述。

總結:

old_list×n = new_list 得到新的list,應該特別注意:

(1) old_list內部的元素是“可變對象”(列表、字典、集合)時,無論是從old_list,還是從new_list 中改變“元素”或“健:值”(通常是利用old_list[][]=或new_list[][]=這種形式操作),都會對所有的對象產生影響;而如果只是對最外層list的對象進行操作(包括替換,重新賦值等,通常是old_list[]=或new_list[]形式),則只影響被操作的對象,不會影響所有對象。

old_list = [[元素,],[元素,],……]

old_list = [{健:值},{健:值},……]

……

(2) old_list內部的元素是“不可變對象”(字符串、數字、元組)時,不存在改變內部元素值的問題(比如下面將‘ab’中的a變為A,這是python不允許的),也就是說old_list[][]=或new_list[][]=這種操作形式不存在。但對最外層list的對象進行操作(包括替換,重新賦值等,通常是old_list[]=或new_list[])與(1)的情況完全相同??梢妼τ诓豢勺儗ο蠖?#xff0c;情況要簡單。

old_list = ['ab','c',……]

old_list = [1,22,……]

old_list = [(1,2),(3,8),……]

……

總結

以上是生活随笔為你收集整理的python长度为n的list_python “list*n”的坑你得注意的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。