获取 Python 字典键的引用

6

在Python(3.7及以上版本)中,我想获取到字典的引用。更确切地说,在以下代码中,假设d是一个字符串作为键的字典。变量k的值可能存储在内存中的两个不同位置(一个由字典指向,另一个由k指向),而变量v的值只存储在一个位置(由字典指向的位置)。

# d is a dict
# k is a string dynamically constructed, in particular not from iterating over d's keys
if k in d:
    v = d[k]
    # Now store k and v in other data structures

在我的情况下,字典非常大,字符串键非常长。为了保持内存使用率低,我想在将 k 存储到其他数据结构之前,使用指向 d 使用的相应字符串的指针来替换它 。有没有一种简单的方法来实现这一点,即使用字典的键作为字符串池?

(注:这似乎是过早优化,也许确实是,但作为一个老派的 C 程序员,我做“内存技巧”会睡得更好。开个玩笑,我真的很想出于好奇知道答案,而且我的确要在树莓派上运行代码,可能会遇到内存问题。)


4
我觉得这是一种(非常)过早的优化。你是否真正遇到了内存问题?如果没有,不要担心,让Python自行管理其内存。 - DeepSpace
无论如何,v = d[k] 不会分配更多的内存。它只是创建了一个名为 v 的引用,指向 d[k] 指向的任何内容。 - DeepSpace
1
你怎么会陷入这种情况?这两个具有相同值的字符串对象从哪里来的? - superb rain
3
如果您在字典 d 中使用了非常长的字符串作为键,是否可以同时存储它们的哈希值 hash(key)?这样当 k in d 为 True 时,可以将相应的键值对存储到 d2[hash(k)] = v 中。 - quamrana
我已经接受下面的答案,因为它提供了一个直接解决我的问题的方法。然而,在实践中,我将放弃我的“过早优化”,并采用哈希和使用不同的方法。我确实感谢上面的评论,比如@DeepSpace所说的“不要担心它”。 - DustByte
显示剩余5条评论
1个回答

7

这个关键字 k 是怎么来的?它是通过类似于 str.join, +, 切片另一个字符串,bytes.decode 或者其他方式动态构建出来的吗? 它是从文件或者 input() 中读取的吗?你是否在某个时刻通过迭代 d 获取到了它?还是它来源于源代码中的某个字面值?

如果是最后两种情况,那么无需担心,因为它总是一个实例。

如果不是,您可以使用 sys.intern 来对关键字进行内部化。如果 a == b,那么 sys.intern(a) is sys.intern(b)

另一个可能的解决方案,以防在某些时候您想要垃圾回收字符串,或者想要内部化一些非字符串值,例如由字符串组成的元组,您可以执行以下操作:

# create this dictionary once after `d` has all the right keys
canonical_keys = {key: key for key in d}

k = canonical_keys.get(k, k) # use the same instance if possible

我建议阅读有关Python数据模型的资料。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接