在 Python 中,我的目標是維護一個唯一的點串列(復數標量,四舍五入),同時用函式穩定地創建新點,就像在這個偽代碼中一樣
list_of_points = []
while True
# generate new point according to some rule
z = generate()
# check whether this point is already there
if z not in list_of_points:
list_of_points.append(z)
if some_condition:
break
現在list_of_points在此程序中可能會變得非常龐大(例如 1000 萬個甚至更多),并且重復非常頻繁。事實上,大約 50% 的時間,一個新創建的點已經在串列中的某個位置。但是,我所知道的是,通常已經存在的點在串列的末尾附近。有時它是“散裝”的,只有極少數情況下才能在開頭附近找到。
這讓我想到了以相反的順序進行搜索。但是,考慮到在此程序中增長的潛在大串列,我將如何最有效地做到這一點(就原始速度而言)。list容器甚至是這里最好的方式嗎?
通過這樣做,我設法獲得了一些性能
list_of_points = []
while True
# generate new point according to some rule
z = generate()
# check very end of list
if z in list_of_points[-10:]:
continue
# check deeper into the list
if z in list_of_points[-100:-10]:
continue
# check the rest
if z not in list_of_points[:-100]:
list_of_points.append(z)
if some_condition:
break
顯然,這不是很優雅。相反,使用第二個 FIFO 型別的容器 (collection.deque) 可以提供大致相同的速度。
uj5u.com熱心網友回復:
您最好的選擇可能是使用集合而不是串列,python 集合使用散列來插入專案,所以它非常快。而且,您可以跳過檢查專案是否已經在串列中的步驟,只需嘗試添加它,如果它已經在集合中,則不會添加它,因為不允許重復。
竊取您的偽代碼示例
set_of_points = {}
while True
# get size of set
a = len(set_of_points)
# generate new point according to some rule
z = generate()
# try to add z to the set
set_of_points.add(z)
b = len(set_of_points)
# if a == b it was not added, thus already existed in the set
if some_condition:
break
uj5u.com熱心網友回復:
使用set. 這就是套裝的用途。啊 - 你已經有答案了。所以我的其他評論:您的這部分代碼似乎不正確:
# check the rest
if z not in list_of_points[100:]:
list_of_points.append(z)
在背景關系中,我相信你打算寫list_of_points[:-100]在那里。您已經檢查了最后 100 個,但是,您正在跳過檢查前100 個。
但更好的是,使用 plain list_of_points。len(list_of_points) - 100隨著串列變長,與復制元素的成本相比,可能進行 100 次冗余比較的成本變得微不足道
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/456732.html
上一篇:按選擇計數(*)欄位排序非常慢
