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

嵌套在Dict理解中的Python集理解,python,nested,dictionary-comprehension,set-comprehension,Python,Nested,Dictionary Comprehension,Set Comprehension,我有一个元组列表,其中每个元组包含一个字符串和一个以下形式的数字: [(string_1, num_a), (string_2, num_b), ...] 字符串是非唯一的,数字也是非唯一的,例如列表中可能存在的(string\u 1,num\u m)或(string\u 9,num\u b) 我试图创建一个以字符串为键的字典,并创建一组以该字符串为值的所有数字: dict = {string_1: {num_a, num_m}, string_2: {num_b}, ...} 我通过以下嵌

我有一个元组列表,其中每个
元组
包含一个
字符串
和一个以下形式的数字:

[(string_1, num_a), (string_2, num_b), ...]
字符串是非唯一的,数字也是非唯一的,例如列表中可能存在的
(string\u 1,num\u m)
(string\u 9,num\u 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
有18000个条目。这段代码对于500个元组的列表运行不到10秒,但是对于18000个元组的列表运行超过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)
这使用确保对于给定的键(字符串值),如果缺少该键,则至少有一个空集可用,然后将当前的
id
值添加到该集

您也可以通过以下方式执行此操作:

defaultdict()
使用传入的工厂为缺少的键设置默认值


defaultdict
方法的缺点是,对象在循环后会继续为丢失的键生成默认值,这可能会隐藏应用程序错误。使用
st_dict.default\u 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'}}

哇,非常有帮助,谢谢你!额外的好处:我不知道dict.setdefault(),并且一直在别处用if语句模拟该功能!再次感谢你!
{'string_9': {'num_b'}, 'string_1': {'num_a', 'num_m'}, 'string_2': {'num_b'}}