【问题标题】:Faster way to add values to existing dictionary?向现有字典添加值的更快方法?
【发布时间】:2017-10-06 15:44:53
【问题描述】:

我有一本词典词典

#Initialize the dictionary
myDict=dict()
for f in ncp:
    myDict[f]={}
    for t in ncp:
        myDict[f][t] = {}

现在我将一个值添加到最低级别(恰好是字典键和 None 值),就像这样,但是我当前的方法很慢

for s in subsetList:
    stIndex = 0
    for f in list(allNodes.intersection(set(s)))
            for t in list(allNodes.difference(set( allNodes.intersection(s)))):
                myDict[f][t]['st_'+str(stIndex)]=None
    stIndex+=1

我尝试使用理解原则来做到这一点,但我失败了,因为我找到的用于理解的示例是创建字典,而不是遍历已经存在的字典来添加。我这样做的尝试甚至不会“编译”:

myDict[f][t]['st_'+str(stIndex)]
    for f in list(allNodes.intersection(set(s)))
       for t in list(allNodes.difference(set( allNodes.intersection(s)))) = None

【问题讨论】:

  • 您能更详细地描述您要解决的一般问题吗?理解创建对象,所以不,它们不是向现有对象添加内容的好方法。
  • 您能描述一下“它太慢”是什么意思以及您期望/想要什么吗?
  • edit您的问题,至少描述您拥有的代码是什么/如何,并且太慢了。还有什么是subsetlistallNones?我们不介意读者。
  • 字典的创建需要不到一秒钟的时间,但迭代构建字典中的内容需要一分钟。我会在今天晚些时候尝试为这个问题添加更多细节。谢谢大家
  • allNodes.intersection(set(s))allNodes.intersection(s) 不同吗?无论如何,您调用后者的次数可能比必要的多得多,因为它的值不会改变内部 for 循环的每次迭代。在将其作为参数传递给allNodes.difference(set( allNodes.intersection(s))) 表达式之前,是否有必要将其结果转换为set

标签: python python-3.x dictionary


【解决方案1】:

我会这样写你的代码:

myDict = {}
for i, s in enumurate(subsetList):
    tpl = ('st_%d' % (i,), None) # Used to create a new {'st_n': None} later
    x = allNodes.intersection(s)
    for f in x:
        myDict[f] = {}
        for t in allNodes.difference(x):
            myDict[f][t] = dict([tpl])

这减少了您需要创建的新对象的数量,以及按需初始化myDict

【讨论】:

  • 感谢 chepner,但这使得它在我的测试中运行得更慢。实际上慢了很多。
  • 您是否在代码的第一部分包括了初始化 myDict 所花费的时间?
  • 是的,慢了很多,我的意思是我让它运行了 30 分钟,它仍然没有完成
【解决方案2】:

这应该更快...

from itertools import product
from collections import defaultdict

mydict = defaultdict(dict)
for f, t in  product(ncp, repeat=2):
    myDict[f][t] = {}
    for s in subsetList:
        myDict[f][t]['st_'+str(stIndex)] = None

或者如果最里面的key level每次都一样……

from itertools import product
from collections import defaultdict

innerDict = {}
for s in subsetList: 
    innerDict['st_'+str(stIndex)] = None

mydict = defaultdict(dict)
for f, t in  product(ncp, repeat=2):
    myDict[f][t] = innerDict.copy()

但我不确定创建最内层字典的副本是否比遍历您的子集列表并每次创建新字典更快。您需要为这两个选项计时。

【讨论】:

  • 谢谢Sasha,我会测试并告诉你进展如何。
  • Sasha,我认为您的解决方案存在一个问题,即 f 和 t 是 s 的函数,我认为您的解决方案不会发生这种情况。例如,ncp 可能是 [a,b,c],因此如果 s1 是 [a,b],那么对于 s 的第一次迭代,您将有 f = a 和 t = c,因为 c 来自 allNodes.difference(s)。基本上,f 表示“从”,t 表示“到”。我们试图“从” s “到” 不在 s 中的所有内容,一次是 s 的一个元素。
【解决方案3】:

在经过多次试验后,在这里用关于最佳方法的理论回答我自己的问题:最终结果是 myDict,它是 2 个元素的函数:allNodes 和 subsetList,这两个元素实际上都是在开始时从 SQL 导入的静态表我的程序。那么,为什么不计算一次 myDict 并将其存储在 SQL 中并导入它。因此,不是每次程序运行时都需要 2 分钟来重建它,而是只需几秒钟的 pyodbc 读取。我知道这有点像警察,但它暂时有效。

【讨论】:

    猜你喜欢
    • 2023-03-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-01
    相关资源
    最近更新 更多