簡體   English   中英

通過循環創建空集的字典,然后使用另一個循環填充這些集 - 更有效的方法? (Python)

[英]Creating a dict of empty sets through a loop, then filling those sets using another loop - more efficient method? (Python)

這個答案中,我通過遍歷一個列表來創建一個空setdict 然后我遍歷同一個列表並填充這些集合。 一個MRE


# imports we need
import time
import numpy as np
np.random.seed(42)

我在做什么

字母列表示例。 請注意,至少一個字母會出現多次。

letters=[np.random.choice([letter for letter in string.ascii_lowercase]) for _ in range(1000)]

結果:

['w', 'n', 'k', 'o', 'm', 'r', ...

創建一個以字母為鍵、空集為值的dict

letterdict={letter:set() for letter in letters}

再次遍歷letters列表,列表中具有相應字母的每個條目將是一個集合,該字母的索引出現在letters列表中:

for index, letter in enumerate(letters):
    letterdict[letter].add(index)

letterdict看起來像:

{'w': {0, 12, 62, 67, 69, ...


過了多久

這個過程花了:

start = time.time()
letterdict={letter:set() for letter in letters}
for index, letter in enumerate(letters):
    letterdict[letter].add(index)
end = time.time()
print(end-start)

0.000538...秒。


問題

有沒有辦法讓letterdict的創建更快? 畢竟,我要遍歷letters兩次。

我的想法:如果我可以在一個循環中完成它,當它第一次遇到一個字母時,我可以創建一個set ,並將該字母的索引放入其中。 第二次遇到字母時,無法重新set ,只需添加索引即可。 然而,檢查一個字母是否已經被遇到過似乎很乏味(即慢)。

在 MRE 中,假設我們不知道所有字母是什么,因此將第一個循環替換為{letter:set() for letter in string.ascii_lowercase}並不是很有用。

你可能想要一個collections.defaultdict

如果鍵不存在,這將在查找時創建空集:

from collections import defaultdict

letterdict = defaultdict(set)
for index, letter in enumerate(letters):
     letterdict[letter].add(index)

這樣您就不必用空集初始化字典。


您可以改為在普通字典上使用.setdefault()方法。

letterdict = {}
for index, letter in enumerate(letters):
     letterdict.setdefault(letter, set()).add(index)

無論是否需要,這都會產生每次創建新集合 object 的開銷,但內置的set()類型似乎構建得非常快。 在我用來計時的小樣本上,它並沒有變慢。 當它們被快速刪除時,CPython 可能會以某種方式匯集它們,就像它對元組所做的那樣。

好的,所以我認為這種方法沒有顯着的時間增益,但是您可以使用一個循環執行相同的工作,方法是使用 try except 塊。

start = time.time()
for index, letter in enumerate(letters):
    try:
        letterdict[letter].add(index)
    except:
        letterdict[letter] = {index}
end = time.time()
print(end-start)

基本上,我們在循環列表時創建了一個集合,因此不需要另一個循環。

我的時間,一是你的方法,二是我的:

0.0009996 #你的方法
0.0009992 #我的方法

正如我所說,沒有顯着的收益,但根據幾次運行,它會稍微快一些。

暫無
暫無

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

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