Получить ссылку на Python dict ключ - PullRequest
4 голосов
/ 02 августа 2020

В Python (3.7 и выше) я хотел бы получить ссылку на dict ключ . Точнее, пусть d будет диктовкой, в которой ключи являются строками. В следующем коде значение k потенциально сохраняется в двух разных местах в памяти (на одно указывает dict, а на другое - k), тогда как значение v хранится только в одном месте (указанном dict).

# 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

В моем случае dict очень большой, а строковые ключи очень длинные. Чтобы уменьшить использование памяти, я хотел бы заменить k указателем на соответствующую строку, используемую d, перед сохранением k в других структурах данных. Есть ли простой способ сделать это, используя ключи dict в качестве пула строк?

( Footnote: это может показаться преждевременной оптимизацией, и, возможно, это так, но будучи программистом старой школы C, я лучше сплю по ночам, выполняя «трюки с памятью». Шутка в сторону, я искренне хотел бы узнать ответ из любопытства, и я действительно собираюсь запустить свой код на Raspberry Pi и вероятно столкнется с проблемами памяти.)

1 Ответ

7 голосов
/ 02 августа 2020

Откуда взялся ключ k? Создается ли он динамически с помощью чего-то вроде str.join, +, разрезая другую строку, bytes.decode et c? Читается из файла или 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 .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...