Быстрый способ скопировать словарь в Python
У меня есть программа Python, которая много работает со словарями. Я должен делать копии словарей тысячи раз. Мне нужна копия обоих ключей и связанного содержимого. Копия будет отредактирована и не должна быть привязана к оригиналу (например, изменения в копии не должны влиять на оригинал.)
Ключи - это строки, значения - это целые числа (0/1).
В настоящее время я использую простой способ:
newDict = oldDict.copy()
Профилирование моего кода показывает, что операция копирования занимает большую часть времени.
Существуют ли более быстрые альтернативы методу dict.copy()
? Что было бы быстрее?
Ответы
Ответ 1
Глядя на источник C для операций Python dict
, вы можете увидеть, что они делают довольно наивную (но эффективную) копию. Это по существу сводится к вызову PyDict_Merge
:
PyDict_Merge(PyObject *a, PyObject *b, int override)
Это позволяет быстро проверять такие вещи, как если они являются одним и тем же объектом и если в них есть объекты. После этого он делает щедрое одноразовое изменение размера/выделение целевому dict, а затем копирует элементы один за другим. Я не вижу, чтобы вы становились намного быстрее, чем встроенный copy()
.
Ответ 2
По-видимому, dict.copy быстрее, как вы говорите.
[[email protected] ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = d.copy()"
1000000 loops, best of 3: 0.238 usec per loop
[[email protected] ~]$ python -m timeit -s "d={1:1, 2:2, 3:3}" "new = dict(d)"
1000000 loops, best of 3: 0.621 usec per loop
[[email protected] ~]$ python -m timeit -s "from copy import copy; d={1:1, 2:2, 3:3}" "new = copy(d)"
1000000 loops, best of 3: 1.58 usec per loop
Ответ 3
Можете ли вы предоставить образец кода, чтобы я мог видеть, как вы используете copy() и в каком контексте?
Вы можете использовать
new = dict(old)
Но я не думаю, что это будет быстрее.
Ответ 4
В зависимости от того, что вы оставляете до спекуляции, вы можете захотеть обернуть оригинальный словарь и сделать вид копирования на запись.
"Копировать" - это словарь, который ищет материал в "родительском" словаре, если он еще не содержит ключ, но сам по себе внесет изменения.
Это предполагает, что вы не будете изменять оригинал и что дополнительные поисковые запросы не будут стоить больше.
Ответ 5
Однако измерения зависят от размера словаря. Для 10000 записей копия (d) и d.copy() почти одинаковы.
a = {b: b for b in range(10000)}
In [5]: %timeit copy(a)
10000 loops, best of 3: 186 µs per loop
In [6]: %timeit deepcopy(a)
100 loops, best of 3: 14.1 ms per loop
In [7]: %timeit a.copy()
1000 loops, best of 3: 180 µs per loop