![](/img/trans.png)
[英]Pythonic way to avoid creation of a new list when iterating over a slice?
[英]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]
下面的代碼說明了在作業的左側使用arr
和arr[:]
之間的區別。
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.