我有一个元组列表,其中每个tuple
包含一个string
和一个以下形式的数字:
[(string_1, num_a), (string_2, num_b), ...]
字符串不是唯一的,数字也是如此,例如<{1}}或(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
}
长达18,000项。这段代码运行500个元组的列表只需不到10秒,但运行完整的18,000个元组需要12分钟以上。我必须认为这是因为我在词典理解中嵌套了一套理解。
有没有办法避免这种情况,或者更聪明的方法呢?
答案 0 :(得分:9)
你有一个双循环,所以你需要O(N ** 2)时间来制作你的字典。对于500件物品,需要250.000步骤,而对于18k物品,需要完成324 百万步骤。
这是一个O(N)循环,因此对于较小的数据集需要500步,对于较大的数据集需要18.000步:
st_dict = {}
for st, id in st_id_list:
st_dict.setdefault(st, set()).add(id)
这使用dict.setdefault()
method来确保对于给定的键(您的字符串值),如果缺少键,则至少有一个空集可用,然后将当前id
值添加到该值集。
您可以使用collections.defaultdict()
object:
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
显式禁用工厂以防止这种情况发生。
答案 1 :(得分:0)
为什么你在这样的循环中使用两个循环:
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'}}