Является ли использование памяти при использовании одного диктора половиной объема, необходимого для двух диктовок?

Допустим, у меня есть 2 словаря на Python, например:

d1 = {}
d2 = {}
d1[(i, j)] = 10
d2[(i, j)] = 20

Вместо этого я мог бы сделать это так:

d = {}
d[(i, j)] = (10, 20)

Доступ к нему можно было сделать с помощью d[(i,j)][0] и d[(i,j)][1].

Я хотел бы спросить вот о чем:

Требуется ли второму варианту меньше памяти, чем первому?

Если да, то это половина памяти?

Мне нужно использовать очень большие словари в программе, которую я пишу, и если второе решение лучше, я бы выбрал его.

Is it half of the memory? - Да.
Olvin Roght 28.05.2019 17:29

Я предлагаю сделать некоторые дальнейшее чтение для словарей в учебнике по Python (подглава 5.5). Затем вы можете лучше указать, что вы хотите сделать. Совсем другое дело, если у вас два отдельных словаря или только один.

lidrariel 28.05.2019 17:30

Вам также следует обратить внимание на более специализированные структуры данных, такие как массивы numpy, которые оптимизированы для данных в матричном стиле.

schlenk 28.05.2019 17:57
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
8
3
178
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Протестировано на машине с Windows 10 в 32-битной версии Python 3.7.3:

Это заняло 155 МБ памяти:

>>> d1 = {(i, j): 10 for i in range(1000) for j in range(1000)}
>>> d2 = {(i, j): 20 for i in range(1000) for j in range(1000)}

А это всего 79МБ:

>>> d = {(i, j): (10, 20) for i in range(1000) for j in range(1000)}

Таким образом, второй, очевидно, лучше с точки зрения использования памяти, но это совершенно разные решения, и трудно сказать, какое из них «лучше» в целом. Все зависит от варианта использования.

 

Редактировать:

Разница намного меньше, но все же значительна при использовании случайных значений (с уникальными ids).

Это заняло 157 МБ:

>>> from random import randint
>>> d1 = {(i, j): randint(0, 100) for i in range(1000) for j in range(1000)}
>>> d2 = {(i, j): randint(0, 100) for i in range(1000) for j in range(1000)}

А это 119 МБ:

>>> from random import randint
>>> d = {(i, j): (randint(0, 100), randint(0, 100)) for i in range(1000) for j in range(1000)}

Это удивительно. Разве кортеж из 2 элементов не занимает больше памяти, чем сами 2 элемента?

Barmar 28.05.2019 17:32

@Barmar Я предполагаю, что да, но дополнительный словарь, очевидно, имеет много накладных расходов.

ruohola 28.05.2019 17:36

Также удивительно, я ожидаю, что это будет асимптотически незначительным. Возможно, в хэш-таблице есть много дополнительного места, чтобы избежать коллизий.

Barmar 28.05.2019 17:37

Является ли второй кортеж 1000 * 1000 или один кортеж и 1000 * 1000 ссылок на один и тот же кортеж?

President James K. Polk 28.05.2019 17:41

@JamesKPolk Это одно и то же id в каждом из них.

ruohola 28.05.2019 17:42

@JamesKPolk >>> id(d[(2,3)]) 17966064, >>> id(d[(999,500)]) 17966064.

ruohola 28.05.2019 17:44

Я не думаю, что OP предполагал, что каждая запись в словаре будет одинаковой.

President James K. Polk 28.05.2019 17:48

Каждая запись не будет отличаться. Применяется ли это в данном случае?

user11568369 28.05.2019 17:51

что если поставить (i,j) вместо (10,20)?

user11568369 28.05.2019 17:54
>>> a = [(10, 20) for i in (0, 1)] >>> a[0] is a[1] True
pts 28.05.2019 17:58

@ruohola Спасибо!! Всего одна маленькая деталь. Если у нас есть 4 элемента (i,j,k,l) ​​вместо 2, не могли бы вы проверить, сколько памяти ему нужно?

user11568369 28.05.2019 17:58

@pikpapo: Вы можете сами проверить использование памяти. Если вы не знаете, как это сделать, задайте отдельный вопрос на StackOverflow.

pts 28.05.2019 17:59

@pikpapo Трудно сравнивать, так как вы не можете разделить 1000000 на 4 цикла равномерно. Вы можете легко проверить использование памяти определенными словарями с помощью диспетчера задач :)

ruohola 28.05.2019 18:01

Итак, мы можем предположить, что чем больше одинаковых элементов, тем меньше памяти требуется словарю?

Epitheoritis 32 28.05.2019 18:15

@Epitheoritis Да, очевидно. Для случайных примеров потребуется создать миллион объектов с уникальными id, что, естественно, требует много памяти.

ruohola 28.05.2019 18:19

Другие вопросы по теме