![](/img/trans.png)
[英]more efficient way of apply where in a loop to different sets of columns - python
[英]Creating a dict of empty sets through a loop, then filling those sets using another loop - more efficient method? (Python)
在這個答案中,我通過遍歷一個列表來創建一個空set
的dict
。 然后我遍歷同一個列表並填充這些集合。 一個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.