簡體   English   中英

有效地從列表中提取元素而不重復

[英]Extract element from a list without repetition efficiently

我需要從一個列表中提取一個准確的值(從累積分布中提取)而不重復(並且還要檢查來自networkx有向圖的另一個約束)。

我的列表有超過 100000 個元素(來自 networkx DiGraph 的某些節點)

我的代碼如下所示:

def extractRandomSubset(alist,number,G #the graph):
    res={}
    count=0
    while count<number:
        el=random.choice(alist) #number extraction
        if el not in res.values() and G.nodes[el]["weight"]!=0: #my two constraints
            res[count]=el
            count+=1                    
    return res

我的代碼從 0.001 秒到 0.5 秒,我需要做 100000 次,所以需要很長時間。 有沒有辦法讓它跑得更快?

最簡單的解決方案是打亂整個列表並獲取符合您的第二個條件的最高count數值:

def extractRandomSubset(_list,number,G):
    from random import shuffle
    shuffle(_list) # now items in _list are shuffled randomly
    ret = []
    for el in _list:
        if len(ret) >= number:
            return ret
        if G.nodes[el]["weight"]!=0:
            ret.append(el)
    # handle the case where you don't have enough nodes with nonzero weights in G
    raise ValueError('Not enough nodes with nonzero weight!')

相同想法的另一個版本首先過濾掉所有沒有正權重的值,然后洗牌:

def extractRandomSubset(_list,number,G):
    from random import shuffle
    valid_items = [el for el in _list if G.nodes[el]["weight"]!=0]
    shuffle(valid_items)
    if len(valid_items) < number:
        raise ValueError('Not enough nodes with nonzero weight!')
    return valid_items[:number]

就個人而言,我更喜歡這個選項,因為:

  1. 語法更簡潔,並且在代碼中清楚地表達了意圖
  2. 您可以通過不一次將一個項目附加到列表來避免多次分配(這可能是減速的一個重要原因)

哪個最快完全取決於_listG中的元素數量和number的值(我希望對於大列表和低number ,第一個選項可能更快)。


PS:調用變量list (因此我使用_list代替)或任何其他掩蓋 python keyworkds/types 的名稱是一個壞主意。

暫無
暫無

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

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