[Python]list.append()在for循环中每次添加的都是最后的一个元素
迷茫
迷茫 2017-04-17 16:39:44
0
2
540
迷茫
迷茫

业精于勤,荒于嬉;行成于思,毁于随。

全部回覆(2)
阿神

首先得知道三點。
1、程式的運作是需要去記憶體申請地址的。
2、賦值運算只是記憶體中某一塊位址的參考。
3、Python 內建的 id()函數。 此函數從概念上可以理解為得到當前生命下的記憶體位址。

id(object)
Return the “identity” of an object. This is an integer which is guaranteed to be unique and constant for this object during its lifetime。

CPython implementation detail: This is the address of the object in memory.

由此我們可以得到以下結果:

a = 1
b = 1
c = a
d = b

print(id(1))                                       # value x
print(id(a))                                       # value x
print(id(b))                                       # value x
print(id(c))                                       # value x
print(id(d))                                       # value x

print(id(1) == id(a) == id(b) == id(c) == id(d))   # True

在此基礎去看 字典/dict :

當宣告一個字典 info = {} 的操作時候,該字典就已經在記憶體中取得了某塊位址。
對該字典進行操作時,如 info['name'] = 'github' 的時候,這個字典依舊是之前所佔用的位址。
可透過id 函數追蹤得到以下程式碼:

info = {}                       
print(id(info))                 # value y

info['name'] = 'github'
print(id(info))                 # value y

因此,對於你改進前的程式碼
pathlist.append(info)添加進去的始終是同一個info,準確的說,始終是同一塊位址,而這個info內容在不停的修改。
參考以下程式碼:

info = {'name': 'github'}
pathlist = [info,]

print(id(info))                 # value z
print(id(pathlist[0]))          # value z

然後,對於改進後的程式碼
info = {} 的操作放在了循環內,結果就是每一次循環都申請使用一段新的地址,只不過依舊用info來引用。
可由一下程式碼對比:

info = {}
print(id(info))                 # value m

info = {}
print(id(info))                 # value n

兩次列印的值是不等的。

另外
第一段程式碼中的
pathlist.append(info) #將dict加入list
這個註釋, 了。

希望能幫到你。

Ty80

原始碼

listDirectory最終回傳的是

[info, info, info...]

而info每次循環都會更新,但最終必為

{'name': last_loop_item}

所以會有那樣的結果

更新程式碼

更新後的程式碼就比較直觀了,
每次info都是新生成的dict,append的是每次循環產生的結果

熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!