簡體   English   中英

遍歷列表時編輯列表(Python方法!)

[英]Edit a list while iterating over it (the pythonic way!)

因此,我知道如何執行此操作,但是對我來說似乎並不是很Python。 有沒有更干凈的方法可以做到這一點?

arr = list(range(10))
print(arr)
for n in range(len(arr)):
    # Perform som operation on the element that changes the value "in place"
    arr[n] += 1
print(arr)

輸出(這就是我想要的):

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

您可以使用列表推導

arr = [i + 1 for i in arr]

這將產生一個列表; 在上面的示例中,我將結果反彈到相同的名稱。

如果您對列表有多個引用,並且需要就地進行更改(因此其他引用可以查看更改),請分配給標識片( [:] )以更新列表的所有索引,而不是重新綁定名稱:

arr[:] = [i + 1 for i in arr]

這將首先創建一個新的列表對象,然后Python足夠聰明,可以看到兩個列表的大小相同,並且僅在元素之間進行復制,然后再次釋放第二個列表。

在這種情況下,您甚至可以使用生成器表達式來避免創建額外的列表:

arr[:] = (i + 1 for i in arr)

這會將原始元素移開,以便為新元素騰出空間,但是不會為此創建新的Python列表對象。 這應該是多一點的內存使用效率。

使用清單理解:

arr = [x + 1 for x in arr]

他們說什么。 但是,如果要在創建列表時進行操作,則可以執行以下操作:

arr = [u + 1 for u in range(10)]

我假設您使用的是Python3。如果您使用的是Python 2,則將range更改為xrange (除非列表大小非常小),因為Python 2 range函數返回一個實際list ,但是xrange返回一個迭代器; Python 3 range函數返回與舊xrange相似的迭代器(但有一些改進)。

如果arr是現有list ,你想不替代目前的修改list有一個新的對象list的對象,你可以做

arr[:] = [u + 1 for u in arr]

下面的代碼說明了在作業的左側使用arrarr[:]之間的區別。

arr = list(range(10))
b = arr
print(id(arr), id(b))
arr = [u + 1 for u in arr]
print(id(arr), id(b))
print(arr, b)

c = arr
print(id(arr), id(c))
arr[:] = [u + 1 for u in arr]
print(id(arr), id(c))
print(arr, c)

輸出

3073636268 3073636268
3073629964 3073636268
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10] [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
3073629964 3073629964
3073629964 3073629964
[2, 3, 4, 5, 6, 7, 8, 9, 10, 11] [2, 3, 4, 5, 6, 7, 8, 9, 10, 11]

因此, arr = [u + 1 for u in arr]將名稱arr綁定到新的列表對象,但是arr[:] = [u + 1 for u in arr]有效地改變了現有列表對象。 它在“內部”下創建一個新的臨時列表對象,然后將其內容復制到舊的列表對象。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM