簡體   English   中英

嵌套在Dict理解中的Python集合理解

[英]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.

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