python - 如果字典不存在,则将其添加到字典中

标签 python dictionary append

我正在尝试编写一些计算 2 的幂的代码,但将它们存储在以 10 的幂作为键的字典中,例如,2^9 将存储为

{0:2, 1:1, 2:5}

你有 5*10^2 + 1*10^1 + 2*10^0。

所以目前,我有类似的东西
def foo():
    result={0:2}
    for i in range(2,10):
        for p in result.keys():
            result[p]*=2
        for p in result.keys():
            if result[p] / 10 != 0:
                result.setdefault(p+1,result[p]/10)
                result[p] = result[p] % 10

问题是
result.setdefault(p+1,result[p]/10)

它会覆盖 result[p+1] 中的任何内容.我知道可以只检查字典,然后在需要时“初始化”新 key ,但是有没有更优雅的方法来即时完成?我可以将结果初始化为足够长,但由于我不一定知道“足够长”有多长,在我看来,即时扩展它更有意义。

基本上我想要一些类似的东西
for p in result.keys():
    if result[p] / 10 != 0:
        if result[p+1] exists:
            result[p+1]+=result[p]/10
        else:
            create result[p+1] and set its value to result[p]/10

非常感谢任何帮助!

最佳答案

因此,您每次通过主循环所做的是:将每个数字加倍,然后将额外的十位带到下一个数字。问题是,对于最高位,下一位不存在。

所以这里有一个解决方案——尽管它不适用于除 2 以外的任何幂,原因我将在下面介绍。

def foo():
    result={0:2}
    for i in range(2,10):
        for p in result.keys():
            result[p]*=2
        for p in result.keys()[:]:
            if result[p] / 10 != 0:
                result[p+1] = result.get(p+1, 0) + result[p] / 10
                result[p] = result[p] % 10

与您的原始代码相比,有两个关键更改。

首先,我们必须添加 [:]到第二个结束result.keys() , 在循环之前迭代字典键集的副本,而不是它的当前键。原因是,如果最后一位数字大于 5,我们将向字典添加一个新键,并且在迭代它时不允许这样做。 (为什么?有几个原因,但最简单的一个是字典的顺序是任意的,每次添加一个键,整个顺序都可以改变。这在后面也很重要。)

其次,这是您最初的问题:如何避免检查 if p+1 in result决定是否存储 r_p或添加 r_p到现有值(value)?

当您处理计数时,您可以使用 collection.Counter ,这就像一个 dict除了它只存储整数,任何缺失的键的值为 0。否则,你通常使用 collection.defaultdict ,这就像一个 dict除了您可以指定所有缺失键都具有的默认值。用一个 Counterdefaultdict ,您只需要 result[p+1] += result[p]/10 .

但我使用了不同的替代方案:get dict上的方法,它允许您指定默认值。我稍后会解释原因,但请记住,一般来说,当您发现自己正在访问 get 时。 ,您可能需要 defaultdictCounter相反。

所以,现在它会以 2 的幂运行和工作。但它不适用于其他幂,原因有两个:

首先,我们以随机顺序进行进位。对于 2 的幂,您最多可以携带 1,并且 1 不可能影响下一个数字是否进位。 (8 不会进位,8+1 也不会进位,现在有办法得到 9。)但对于任何其他力量,这不是真的。

在简单的测试中,你可能不会注意到这一点,因为当你从一个空的 dict 开始时(至少在 CPython 2.7 和 3.2 中)。并按排序顺序添加少量小键(实际上是具有小哈希值的键,但小整数对自身进行哈希),并且不要删除任何内容,dict通常会按顺序迭代(和打印)。但总的来说,顺序是不可预测的,你不能依赖它。

该问题的解决方案是使用 collections.OrderedDict ,它按照键的添加顺序迭代键。这就是为什么我不想使用 defaultdictCounter : 因为如果你必须切换到 OrderedDict ,您唯一的选择是 get .

其次,一旦你的指数超过 10,你可能需要进位 100。这意味着你必须进位 10,这会导致下一个数字即使是 0 也进位。这意味着我们不能只是复制里面的键提前。例如,假设我们正在做 75 次幂。从 {0:5, 1:7} 开始。 .将每个数字乘以 75 到 {0:375, 1:525} .现在携带37:{0:5, 1:562} .现在携带56:{0:5, 1:2, 2:56} .因为我们只是迭代原始键的副本——即 [0, 1] ——我们没有机会携带 5。

我会让你来解决这个问题。

但是,您可能需要考虑的一件事是创建一个新字典,而不是就地修改旧字典。然后你就可以解决所有这些问题。 (作为一般规则,使用纯函数而不是改变状态会解决很多问题,但当然要以额外的复制为代价。)
def double(d):
    result = Counter()
    for p in d:
        result[p] += d[p] % 10
        result[p+1] += d[p] / 10
    return result

digits={0:2}
for i in range(2,10):
    for p in digits:
        digits[p]*=2
    digits = double(digits)

关于python - 如果字典不存在,则将其添加到字典中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12649855/

相关文章:

python - 如何查找 Pandas 时间索引中的漏洞

python - psutil:获取所有进程的cpu

javascript - 使用 JavaScript (jquery) 编写 HTML 代码

javascript - jquery .append iframe 动画

c++ - 将类映射到字符串

scheme - append !在计划?

python - Python 中 numpy.random.rand 与 numpy.random.randn 之间的区别

python - 使用 Scrapy 进行条件 URL 抓取

iOS swift : How to calculate the sum of each value in a key-pair dictionary and store it in a separate dictionary?

python - 从列表中的字符串创建字典?