[英]Python Set Comprehension Nested in Dict Comprehension
我有一個元組列表,其中每個tuple
包含一個string
和一個數字形式:
[(string_1, num_a), (string_2, num_b), ...]
字符串是非唯一的,數字也是如此,例如(string_1 , num_m)
或(string_9 , num_b)
可能存在於列表中。
我正在嘗試使用字符串作為鍵創建一個字典,並使用該字符串作為值創建一組所有數字:
dict = {string_1: {num_a, num_m}, string_2: {num_b}, ...}
我已經成功地使用嵌套集合理解的以下字典理解:
#st_id_list = [(string_1, num_a), ...]
#st_dict = {string_1: {num_a, num_m}, ...}
st_dict = {
st[0]: set(
st_[1]
for st_ in st_id_list
if st_[0] == st[0]
)
for st in st_id_list
}
只有一個問題: st_id_list
是18,000項長。 這段代碼運行500個元組的列表只需不到10秒,但運行完整的18,000個元組需要12分鍾以上。 我必須認為這是因為我在dict理解中嵌套了一套理解。
有沒有辦法避免這種情況,或者更聰明的方法呢?
你有一個雙循環,所以你需要O(N ** 2)時間來制作你的字典。 對於500件物品,采取250.000步驟,對於18k物品,需要完成3.24 億步驟。
這是一個O(N)循環,因此對於較小的數據集需要500步,對於較大的數據集需要18.000步:
st_dict = {}
for st, id in st_id_list:
st_dict.setdefault(st, set()).add(id)
這使用dict.setdefault()
方法來確保對於給定的鍵(您的字符串值),如果缺少鍵,則至少有一個空集可用,然后將當前的id
值添加到該集。
您可以使用collections.defaultdict()
對象執行相同的操作:
from collections import defaultdict
st_dict = defaultdict(set)
for st, id in st_id_list:
st_dict[st].add(id)
defaultdict()
使用傳入的工廠為缺失鍵設置默認值。
defaultdict
方法的缺點是對象在循環后繼續為缺少的鍵生成默認值,這可以隱藏應用程序錯誤。 使用st_dict.default_factory = None
可以顯式禁用工廠以防止這種情況發生。
為什么你在一個循環中使用兩個循環,如下所示:
list_1=[('string_1', 'num_a'), ('string_2', 'num_b'),('string_1' , 'num_m'),('string_9' , 'num_b')]
string_num={}
for i in list_1:
if i[0] not in string_num:
string_num[i[0]]={i[1]}
else:
string_num[i[0]].add(i[1])
print(string_num)
輸出:
{'string_9': {'num_b'}, 'string_1': {'num_a', 'num_m'}, 'string_2': {'num_b'}}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.